Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
416203 | 52 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ERC1155EditionsDFS
Compiler Version
v0.8.10+commit.fc410830
ZkSolc Version
v1.5.6
Optimization Enabled:
Yes with Mode z
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "./interfaces/IERC1155EditionsDFS.sol"; import "./ERC1155Base.sol"; import "../utils/Ownable.sol"; import "../metadata/interfaces/IMetadataRenderer.sol"; import "../metadata/interfaces/IEditionsMetadataRenderer.sol"; import "../auction/interfaces/IAuctionManager.sol"; import "../erc721/interfaces/IEditionCollection.sol"; import "../tokenManager/interfaces/IPostTransfer.sol"; import "../tokenManager/interfaces/IPostBurn.sol"; import "../tokenManager/interfaces/ITokenManagerEditions.sol"; import "../erc721/interfaces/IERC721EditionMint.sol"; import "../utils/ERC1155/ERC1155Upgradeable.sol"; import "../mint/interfaces/IAbridgedMintVector.sol"; import "../mint/mechanics/interfaces/IMechanicMintManager.sol"; import "./interfaces/IERC1155Standard.sol"; /** * @title ERC1155 Editions * @author highlight.xyz * @notice Multiple Editions Per Collection * @dev Using Decentralized File Storage */ contract ERC1155EditionsDFS is IEditionCollection, IERC1155EditionsDFS, IERC721EditionMint, ERC1155Base, ERC1155Upgradeable, IERC1155Standard { using EnumerableSet for EnumerableSet.AddressSet; /** * @notice Throw when edition doesn't exist */ error EditionDoesNotExist(); /** * @notice Throw when token doesn't exist */ error TokenDoesNotExist(); /** * @notice Throw when attempting to mint, while mint is frozen */ error MintFrozen(); /** * @notice Throw when tokens on edition are sold out */ error SoldOut(); /** * @notice Throw when edition size is invalid */ error InvalidSize(); /** * @notice Throw when edition burn is invalid */ error InvalidBurn(); /** * @notice Throw when edition metadata update is blocked */ error MetadataUpdateBlocked(); /** * @notice Throw when edition size update is invalid */ error InvalidEditionSizeUpdate(); /** * @notice Throw when edition size is updated */ event HighlightUpdated1155EditionSize(uint256 indexed editionId, uint128 oldSize, uint128 newSize); /** * @notice Track each token's current supply and max supply */ struct EditionSupply { uint128 currentSupply; uint128 maxSupply; } /** * @notice Contract metadata */ string public contractURI; string public name; string public symbol; /** * @notice Keeps track of next token ID */ uint256 public nextTokenId; /** * @notice Tracks each edition/token's supply */ mapping(uint256 => EditionSupply) public editionSupply; /** * @notice Track metadata per edition */ mapping(uint256 => string) private _editionURI; /** * @notice Emitted when edition is created * @param editionId Edition/token ID * @param size Edition size * @param editionTokenManager Token manager for edition */ event EditionCreated(uint256 indexed editionId, uint256 indexed size, address indexed editionTokenManager); /** * @notice Initialize the contract * @param creator Creator/owner of contract * @param data Contract initialization data * @ param _contractURI Contract metadata * @ param _name Name of token edition * @ param _symbol Symbol of the token edition * @ param trustedForwarder Trusted minimal forwarder * @ param initialMinters Initial minters to register * @ param useMarketplaceFiltererRegistry Denotes whether to use marketplace filterer registry * @ param _observability Observability contract address */ function initialize(address creator, bytes memory data) external initializer { ( string memory _contractURI, string memory _name, string memory _symbol, address trustedForwarder, address[] memory initialMinters, bool useMarketplaceFiltererRegistry, address _observability ) = abi.decode(data, (string, string, string, address, address[], bool, address)); IRoyaltyManager.Royalty memory _defaultRoyalty = IRoyaltyManager.Royalty(address(0), 0); _initialize( creator, _defaultRoyalty, address(0), _contractURI, _name, _symbol, trustedForwarder, initialMinters, useMarketplaceFiltererRegistry, _observability ); } /** * @notice Create edition * @param _editionUri Edition uri (metadata) * @param _editionSize Size of the Edition * @param _editionTokenManager Edition's token manager * @param editionRoyalty Edition royalty object for contract (optional) * @param mintVectorData Direct mint vector data * @notice Used to create a new Edition within the Collection */ function createEdition( string memory _editionUri, uint256 _editionSize, address _editionTokenManager, IRoyaltyManager.Royalty memory editionRoyalty, bytes calldata mintVectorData ) external onlyOwner nonReentrant returns (uint256) { uint256 editionId = _createEdition(_editionUri, _editionSize, _editionTokenManager); if (editionRoyalty.recipientAddress != address(0)) { _royalties[editionId] = editionRoyalty; } if (mintVectorData.length > 0) { ( address mintManager, address paymentRecipient, uint48 startTimestamp, uint48 endTimestamp, uint192 pricePerToken, uint48 tokenLimitPerTx, uint48 maxTotalClaimableViaVector, uint48 maxUserClaimableViaVector, address currency ) = abi.decode( mintVectorData, (address, address, uint48, uint48, uint192, uint48, uint48, uint48, address) ); IAbridgedMintVector(mintManager).createAbridgedVector( IAbridgedMintVector.AbridgedVectorData( uint160(address(this)), startTimestamp, endTimestamp, uint160(paymentRecipient), maxTotalClaimableViaVector, 0, uint160(currency), tokenLimitPerTx, maxUserClaimableViaVector, pricePerToken, uint48(editionId), // cast down true, false, 0 ) ); } return editionId; } /** * @notice Used to create a new Edition within the Collection * @param _editionUri Edition uri (metadata) * @param _editionSize Size of the Edition * @param _editionTokenManager Edition's token manager * @param editionRoyalty Edition royalty object for contract (optional) * @param mechanicVectorData Mechanic mint vector data * @ param mechanicVectorId Global mechanic vector ID * @ param mechanic Mechanic address * @ param mintManager Mint manager address * @ param vectorData Vector data */ function createEditionWithMechanicVector( string memory _editionUri, uint256 _editionSize, address _editionTokenManager, IRoyaltyManager.Royalty memory editionRoyalty, bytes calldata mechanicVectorData ) external onlyOwner nonReentrant returns (uint256) { uint256 editionId = _createEdition(_editionUri, _editionSize, _editionTokenManager); if (editionRoyalty.recipientAddress != address(0)) { _royalties[editionId] = editionRoyalty; } if (mechanicVectorData.length > 0) { (uint96 seed, address mechanic, address mintManager, bytes memory vectorData) = abi.decode( mechanicVectorData, (uint96, address, address, bytes) ); IMechanicMintManager(mintManager).registerMechanicVector( IMechanicData.MechanicVectorMetadata(address(this), uint96(editionId), mechanic, true, false, false), seed, vectorData ); } return editionId; } /** * @notice Used to create a new Edition within the Collection * @param _editionUri Edition uri (metadata) * @param _editionSize Size of the Edition * @param _editionTokenManager Edition's token manager * @param editionRoyalty Edition royalty object for contract (optional) * @param mintVectorData Direct mint vector data * @param mechanicVectorData Mechanic mint vector data * @ param mechanicVectorId Global mechanic vector ID * @ param mechanic Mechanic address * @ param mintManager Mint manager address * @ param vectorData Vector data */ function createEditionWithMechanicVectorAndPublicFixedPriceVector( string memory _editionUri, uint256 _editionSize, address _editionTokenManager, IRoyaltyManager.Royalty memory editionRoyalty, bytes calldata mintVectorData, bytes calldata mechanicVectorData ) external onlyOwner nonReentrant returns (uint256) { uint256 editionId = _createEdition(_editionUri, _editionSize, _editionTokenManager); if (editionRoyalty.recipientAddress != address(0)) { _royalties[editionId] = editionRoyalty; } if (mintVectorData.length > 0) { ( address mintManager, address paymentRecipient, uint48 startTimestamp, uint48 endTimestamp, uint192 pricePerToken, uint48 tokenLimitPerTx, uint48 maxTotalClaimableViaVector, uint48 maxUserClaimableViaVector, address currency ) = abi.decode( mintVectorData, (address, address, uint48, uint48, uint192, uint48, uint48, uint48, address) ); IAbridgedMintVector(mintManager).createAbridgedVector( IAbridgedMintVector.AbridgedVectorData( uint160(address(this)), startTimestamp, endTimestamp, uint160(paymentRecipient), maxTotalClaimableViaVector, 0, uint160(currency), tokenLimitPerTx, maxUserClaimableViaVector, pricePerToken, uint48(editionId), // cast down true, false, 0 ) ); } if (mechanicVectorData.length > 0) { (uint96 seed, address mechanic, address mintManager, bytes memory vectorData) = abi.decode( mechanicVectorData, (uint96, address, address, bytes) ); IMechanicMintManager(mintManager).registerMechanicVector( IMechanicData.MechanicVectorMetadata(address(this), uint96(editionId), mechanic, true, false, false), seed, vectorData ); } return editionId; } /** * @notice See {IERC721EditionMint-mintOneToRecipient} */ function mintOneToRecipient( uint256 editionId, address recipient ) external onlyMinter nonReentrant returns (uint256) { if (_mintFrozen == 1) { _revert(MintFrozen.selector); } if (!_editionExists(editionId)) { _revert(EditionDoesNotExist.selector); } return _mintEditionsToOne(editionId, recipient, 1); } /** * @notice See {IERC721EditionMint-mintAmountToRecipient} */ function mintAmountToRecipient( uint256 editionId, address recipient, uint256 amount ) external onlyMinter nonReentrant returns (uint256) { if (_mintFrozen == 1) { _revert(MintFrozen.selector); } if (!_editionExists(editionId)) { _revert(EditionDoesNotExist.selector); } return _mintEditionsToOne(editionId, recipient, amount); } /** * @notice See {IERC721EditionMint-mintOneToRecipients} */ function mintOneToRecipients( uint256 editionId, address[] memory recipients ) external onlyMinter nonReentrant returns (uint256) { if (_mintFrozen == 1) { _revert(MintFrozen.selector); } if (!_editionExists(editionId)) { _revert(EditionDoesNotExist.selector); } return _mintEditions(editionId, recipients, 1); } /** * @notice See {IERC721EditionMint-mintAmountToRecipients} */ function mintAmountToRecipients( uint256 editionId, address[] memory recipients, uint256 amount ) external onlyMinter nonReentrant returns (uint256) { if (_mintFrozen == 1) { _revert(MintFrozen.selector); } if (!_editionExists(editionId)) { _revert(EditionDoesNotExist.selector); } return _mintEditions(editionId, recipients, amount); } /** * @notice Set contract name * @param newName New name * @param newSymbol New symbol * @param newContractUri New contractURI */ function setContractMetadata( string calldata newName, string calldata newSymbol, string calldata newContractUri ) external onlyOwner { _setContractMetadata(newName, newSymbol); contractURI = newContractUri; observability.emitContractMetadataSet(newName, newSymbol, newContractUri); } /** * @notice Set an Edition's uri * @param editionId Edition to set uri for * @param _uri Uri to set on editions */ function setEditionURI(uint256 editionId, string memory _uri) external { address _manager = tokenManager(editionId); address msgSender = _msgSender(); if (_manager == address(0)) { address tempOwner = owner(); if (msgSender != tempOwner) { _revert(Unauthorized.selector); } } else { if ( !ITokenManagerEditions(_manager).canUpdateEditionsMetadata( address(this), msgSender, editionId, bytes(_uri), ITokenManagerEditions.FieldUpdated.other ) ) { _revert(MetadataUpdateBlocked.selector); } } _editionURI[editionId] = _uri; uint256[] memory _ids = new uint256[](1); _ids[0] = editionId; string[] memory _uris = new string[](1); _uris[0] = _uri; observability.emitTokenURIsSet(_ids, _uris); } /** * @notice Set the edition size */ function setEditionSize(uint256 editionId, uint128 newSize) external onlyOwner { if (!_editionExists(editionId)) { _revert(EditionDoesNotExist.selector); } EditionSupply memory editionMetadata = editionSupply[editionId]; // cannot: // - currently update the size of an open edition // - currently update a limited edition to an open edition // update the size to a value lower than the current supply if ( editionMetadata.maxSupply == 0 || (editionMetadata.maxSupply != 0 && newSize == 0) || newSize < editionMetadata.currentSupply ) { _revert(InvalidEditionSizeUpdate.selector); } emit HighlightUpdated1155EditionSize(editionId, editionMetadata.maxSupply, newSize); editionSupply[editionId].maxSupply = newSize; } /** * @notice See {IERC1155Standard-highlightContractStandardHash} */ function highlightContractStandardHash() external view returns (bytes32) { return 0x3a9654d81ac4dafbb9a2fb1cd3efa3de2783ae40b06b17a456bf5922ed02a3a7; } /** * @notice See {IEditionCollection-getEditionDetails} */ function getEditionDetails(uint256 editionId) external view returns (EditionDetails memory) { if (!_editionExists(editionId)) { _revert(EditionDoesNotExist.selector); } return _getEditionDetails(editionId); } /** * @notice See {IEditionCollection-getEditionsDetailsAndUri} */ function getEditionsDetailsAndUri( uint256[] calldata editionIds ) external view returns (EditionDetails[] memory, string[] memory) { uint256 editionIdsLength = editionIds.length; EditionDetails[] memory editionsDetails = new EditionDetails[](editionIdsLength); string[] memory uris = new string[](editionIdsLength); for (uint256 i = 0; i < editionIdsLength; i++) { uris[i] = editionURI(editionIds[i]); editionsDetails[i] = _getEditionDetails(editionIds[i]); } return (editionsDetails, uris); } /** * @notice Total supply of NFTs on the Editions */ function totalSupply() external view returns (uint256) { return nextTokenId - 1; } /** * @notice See {IERC1155-burn}. Overrides default behaviour to check associated tokenManager. */ function burn(address from, uint256 tokenId, uint256 amount) public nonReentrant { address _manager = tokenManager(tokenId); address msgSender = _msgSender(); uint128 _currentSupply = editionSupply[tokenId].currentSupply; if (amount > _currentSupply) { _revert(InvalidBurn.selector); } if (_manager != address(0) && IERC165Upgradeable(_manager).supportsInterface(type(IPostBurn).interfaceId)) { IPostBurn(_manager).postBurn(msgSender, from, tokenId); } else { // default to restricting burn to owner or operator if a valid TM isn't present if (!(isApprovedForAll(from, msgSender) || msgSender == from)) { _revert(Unauthorized.selector); } } _burn(from, tokenId, amount); editionSupply[tokenId].currentSupply = _currentSupply - uint128(amount); observability.emitTransferSingle(msgSender, from, address(0), tokenId, amount); } /** * @notice Conforms to ERC-2981. * @param _tokenId Token id * @param _salePrice Sale price of token */ function royaltyInfo( uint256 _tokenId, uint256 _salePrice ) public view virtual override returns (address receiver, uint256 royaltyAmount) { return ERC1155Base.royaltyInfo(_tokenId, _salePrice); } /** * @notice See {IEditionCollection-getEditionId} */ function getEditionId(uint256 tokenId) public view returns (uint256) { if (!_editionExists(tokenId)) { _revert(TokenDoesNotExist.selector); } return tokenId; } /** * @notice Used to get token manager of token id * @param tokenId ID of the token */ function tokenManagerByTokenId(uint256 tokenId) public view returns (address) { return tokenManager(tokenId); } /** * @notice Get URI for given edition id * @param editionId edition id to get uri for */ function editionURI(uint256 editionId) public view returns (string memory) { if (!_editionExists(editionId)) { _revert(EditionDoesNotExist.selector); } return _editionURI[editionId]; } /** * @notice Get URI for given token id * @param tokenId token id to get uri for */ function tokenURI(uint256 tokenId) public view returns (string memory) { if (!_editionExists(tokenId)) { _revert(TokenDoesNotExist.selector); } return _editionURI[tokenId]; } /** * @notice Get URI for given token id * @param tokenId token id to get uri for */ function uri(uint256 tokenId) public view override returns (string memory) { return tokenURI(tokenId); } /** * @notice See {IERC1155Upgradeable-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(IERC165Upgradeable, ERC1155Upgradeable) returns (bool) { return ERC1155Upgradeable.supportsInterface(interfaceId); } /** * @notice Private function to mint without any access checks. Called by the public edition minting functions. * @param editionId Edition being minted on * @param recipients Recipients of newly minted tokens * @param _amount Amount minted to each recipient */ function _mintEditions(uint256 editionId, address[] memory recipients, uint256 _amount) internal returns (uint256) { uint256 recipientsLength = recipients.length; EditionSupply memory _editionSupply = editionSupply[editionId]; uint256 newSupply = _editionSupply.currentSupply + (recipientsLength * _amount); if (_editionSupply.maxSupply > 0 && newSupply > _editionSupply.maxSupply) { _revert(SoldOut.selector); } for (uint256 i = 0; i < recipientsLength; i++) { _mint(recipients[i], editionId, _amount, ""); } editionSupply[editionId].currentSupply = uint128(newSupply); return newSupply; } /** * @notice Private function to mint without any access checks. Called by the public edition minting functions. * @param editionId Edition being minted on * @param recipient Recipient of newly minted token * @param _amount Amount minted to recipient */ function _mintEditionsToOne(uint256 editionId, address recipient, uint256 _amount) internal returns (uint256) { EditionSupply memory _editionSupply = editionSupply[editionId]; uint256 newSupply = _editionSupply.currentSupply + _amount; if (_editionSupply.maxSupply > 0 && newSupply > _editionSupply.maxSupply) { _revert(SoldOut.selector); } _mint(recipient, editionId, _amount, ""); editionSupply[editionId].currentSupply = uint128(newSupply); return newSupply; } /** * @notice Hook called after transfers * @param from Account token is being transferred from * @param to Account token is being transferred to * @param ids IDs of tokens being transferred * @param amounts Amounts of tokens being transferred * @ param data Data associated with transfer */ function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory /* data */ ) internal override { address msgSender = operator; uint256 idsLength = ids.length; for (uint256 i = 0; i < idsLength; i++) { address _manager = tokenManagerByTokenId(ids[i]); if ( _manager != address(0) && IERC165Upgradeable(_manager).supportsInterface(type(IPostTransfer).interfaceId) ) { IPostTransfer(_manager).postTransferFrom(msgSender, from, to, ids[i]); } } if (idsLength == 1) { observability.emitTransferSingle(msgSender, from, to, ids[0], amounts[0]); } else { observability.emitTransferBatch(msgSender, from, to, ids, amounts); } } /** * @notice Returns whether `editionId` exists. * @param editionId Id of edition being checked */ function _editionExists(uint256 editionId) internal view returns (bool) { return editionId < nextTokenId; } /** * @notice Used for meta-transactions */ function _msgSender() internal view override(ERC1155Base, ContextUpgradeable) returns (address sender) { return ERC2771ContextUpgradeable._msgSender(); } /** * @notice Used for meta-transactions */ function _msgData() internal view override(ERC1155Base, ContextUpgradeable) returns (bytes calldata) { return ERC2771ContextUpgradeable._msgData(); } /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure override(ERC1155Base, ERC1155Upgradeable) { ERC1155Base._revert(errorSelector); } /** * @notice Initialize the contract * @param creator Creator/owner of contract * @param defaultRoyalty Default royalty object for contract (optional) * @param _defaultTokenManager Default token manager for contract (optional) * @param _contractURI Contract metadata * @param _name Name of token edition * @param _symbol Symbol of the token edition * @param trustedForwarder Trusted minimal forwarder * @param initialMinters Initial minters to register * @param useMarketplaceFiltererRegistry Denotes whether to use marketplace filterer registry * @param _observability Observability contract address */ function _initialize( address creator, IRoyaltyManager.Royalty memory defaultRoyalty, address _defaultTokenManager, string memory _contractURI, string memory _name, string memory _symbol, address trustedForwarder, address[] memory initialMinters, bool useMarketplaceFiltererRegistry, address _observability ) private { __ERC1155Base_initialize(creator, defaultRoyalty, _defaultTokenManager); _setContractMetadata(_name, _symbol); __ERC2771ContextUpgradeable__init__(trustedForwarder); // deprecate but keep input for backwards-compatibility: // __MarketplaceFilterer__init__(useMarketplaceFiltererRegistry); uint256 initialMintersLength = initialMinters.length; for (uint256 i = 0; i < initialMintersLength; i++) { _minters.add(initialMinters[i]); } nextTokenId = 1; contractURI = _contractURI; IObservabilityV2(_observability).emitEditions1155Deployed(address(this)); observability = IObservabilityV2(_observability); } /** * @notice Create edition * @param _editionUri Edition uri (metadata) * @param _editionSize Size of the Edition * @param _editionTokenManager Edition's token manager * @notice Used to create a new Edition within the Collection */ function _createEdition( string memory _editionUri, uint256 _editionSize, address _editionTokenManager ) private returns (uint256) { uint256 editionId = nextTokenId; nextTokenId = editionId + 1; editionSupply[editionId] = EditionSupply(0, uint128(_editionSize)); _editionURI[editionId] = _editionUri; if (_editionTokenManager != address(0)) { if (!_isValidTokenManager(_editionTokenManager)) { _revert(InvalidManager.selector); } _managers[editionId] = _editionTokenManager; } emit EditionCreated(editionId, _editionSize, _editionTokenManager); return editionId; } /** * @dev Set name / symbol */ function _setContractMetadata(string memory newName, string memory newSymbol) private { name = newName; symbol = newSymbol; } /** * @notice Get edition details * @param editionId Id of edition to get details for */ function _getEditionDetails(uint256 editionId) private view returns (EditionDetails memory) { return EditionDetails("", editionSupply[editionId].maxSupply, editionSupply[editionId].currentSupply, editionId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity 0.8.10; import "@openzeppelin/contracts/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. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ /* solhint-disable */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @notice Used to interface with core of EditionsMetadataRenderer * @author Zora, [email protected] */ interface IMetadataRenderer { /** * @notice Store metadata for an edition * @param data Metadata */ function initializeMetadata(bytes memory data) external; /** * @notice Get uri for token * @param tokenId ID of token to get uri for */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.10; import { IMinimalForwarder } from "./IMinimalForwarder.sol"; /** * @title Interface for AuctionManager * @notice Defines behaviour encapsulated in AuctionManager * @author highlight.xyz */ interface IAuctionManager { /** * @notice The state an auction is in * @param NON_EXISTENT Default state of auction pre-creation * @param LIVE_ON_CHAIN State of auction after creation but before the auction ends or is cancelled * @param CANCELLED_ON_CHAIN State of auction after auction is cancelled * @param FULFILLED State of auction after winning bid has been dispersed and NFT has left escrow */ enum AuctionState { NON_EXISTENT, LIVE_ON_CHAIN, CANCELLED_ON_CHAIN, FULFILLED } /** * @notice The data structure containing all fields on an English Auction that need to be on-chain * @param collection The collection hosting the auctioned NFT * @param currency The currency bids must be made in * @param owner The auction owner * @param paymentRecipient The recipient account of the winning bid * @param endTime When the auction will tentatively end. Is 0 if first bid hasn't been made * @param tokenId The ID of the NFT being auctioned * @param mintWhenReserveMet If true, new NFT will be minted when reserve crossing bid is made * @param state Auction state */ struct EnglishAuction { address collection; address currency; address owner; address payable paymentRecipient; uint256 endTime; uint256 tokenId; // if nft already exists bool mintWhenReserveMet; AuctionState state; } /** * @notice Used for information about auctions on editions * @param used True if the auction is for an auction on an edition * @param editionId ID of the edition used for this auction */ struct EditionAuction { bool used; uint256 editionId; } /** * @notice Data required for a bidder to make a bid. Claims are signed, hashed and validated, acting as bid keys * @param auctionId ID of auction * @param bidPrice Price that bidder is bidding * @param reservePrice Price that bidder must bid greater than. Only relevant for the first bid on an auction * @param maxClaimsPerAccount Max bids that an account can make on an auction. Unlimited if 0 * @param claimExpiryTimestamp Time when claim expires * @param buffer Minimum time that must be left in an auction after a bid is made * @param minimumIncrementPerBidPctBPS Minimum % that a bid must be higher than the previous highest bid by, * in basis points * @param claimer Account that can use the claim */ struct Claim { bytes32 auctionId; uint256 bidPrice; uint256 reservePrice; uint256 maxClaimsPerAccount; uint256 claimExpiryTimestamp; uint256 buffer; uint256 minimumIncrementPerBidPctBPS; address payable claimer; } /** * @notice Structure hosting highest bidder info * @param bidder Bidder with current highest bid * @param preferredNFTRecipient The account that the current highest bidder wants the NFT to go to if they win. * Useful for non-transferable NFTs being auctioned. * @param amount Amount of current highest bid */ struct HighestBidderData { address payable bidder; address preferredNFTRecipient; uint256 amount; } /** * @notice Emitted when an english auction is created * @param auctionId ID of auction * @param owner Auction owner * @param collection Collection that NFT being auctioned is on * @param tokenId ID of NFT being auctioned * @param currency The currency bids must be made in * @param paymentRecipient The recipient account of the winning bid * @param endTime Auction end time */ event EnglishAuctionCreated( bytes32 indexed auctionId, address indexed owner, address indexed collection, uint256 tokenId, address currency, address paymentRecipient, uint256 endTime ); /** * @notice Emitted when a valid bid is made on an auction * @param auctionId ID of auction * @param bidder Bidder with new highest bid * @param firstBid True if this is the first bid, ie. first bid greater than reserve price * @param collection Collection that NFT being auctioned is on * @param tokenId ID of NFT being auctioned * @param value Value of bid * @param timeLengthened True if this bid extended the end time of the auction (by being bid >= endTime - buffer) * @param preferredNFTRecipient The account that the current highest bidder wants the NFT to go to if they win. * Useful for non-transferable NFTs being auctioned. * @param endTime The current end time of the auction */ event Bid( bytes32 indexed auctionId, address indexed bidder, bool indexed firstBid, address collection, uint256 tokenId, uint256 value, bool timeLengthened, address preferredNFTRecipient, uint256 endTime ); /** * @notice Emitted when an auction's end time is extended * @param auctionId ID of auction * @param tokenId ID of NFT being auctioned * @param collection Collection that NFT being auctioned is on * @param buffer Minimum time that must be left in an auction after a bid is made * @param newEndTime New end time of auction */ event TimeLengthened( bytes32 indexed auctionId, uint256 indexed tokenId, address indexed collection, uint256 buffer, uint256 newEndTime ); /** * @notice Emitted when an auction is won, and its terms are fulfilled * @param auctionId ID of auction * @param tokenId ID of NFT being auctioned * @param collection Collection that NFT being auctioned is on * @param owner Auction owner * @param winner Winning bidder * @param paymentRecipient The recipient account of the winning bid * @param nftRecipient The account receiving the auctioned NFT * @param currency The currency bids were made in * @param amount Winning bid value * @param paymentRecipientPctBPS The percentage of the winning bid going to the paymentRecipient, in basis points */ event AuctionWon( bytes32 indexed auctionId, uint256 indexed tokenId, address indexed collection, address owner, address winner, address paymentRecipient, address nftRecipient, address currency, uint256 amount, uint256 paymentRecipientPctBPS ); /** * @notice Emitted when an auction is cancelled on-chain (before any valid bids have been made). * @param auctionId ID of auction * @param owner Auction owner * @param collection Collection that NFT was being auctioned on * @param tokenId ID of NFT that was being auctioned */ event AuctionCanceledOnChain( bytes32 indexed auctionId, address indexed owner, address indexed collection, uint256 tokenId ); /** * @notice Emitted when the payment recipient of an auction is updated * @param auctionId ID of auction * @param owner Auction owner * @param newPaymentRecipient New payment recipient of auction */ event PaymentRecipientUpdated( bytes32 indexed auctionId, address indexed owner, address indexed newPaymentRecipient ); /** * @notice Emitted when the preferred NFT recipient of an auctionbid is updated * @param auctionId ID of auction * @param owner Auction owner * @param newPreferredNFTRecipient New preferred nft recipient of auction */ event PreferredNFTRecipientUpdated( bytes32 indexed auctionId, address indexed owner, address indexed newPreferredNFTRecipient ); /** * @notice Emitted when the end time of an auction is updated * @param auctionId ID of auction * @param owner Auction owner * @param newEndTime New end time */ event EndTimeUpdated(bytes32 indexed auctionId, address indexed owner, uint256 indexed newEndTime); /** * @notice Emitted when the platform is updated * @param newPlatform New platform */ event PlatformUpdated(address newPlatform); /** * @notice Create an auction that mints the NFT being auctioned into escrow (mints the next NFT on the collection) * @param auctionId ID of auction * @param auction The auction details */ function createAuctionForNewToken(bytes32 auctionId, EnglishAuction memory auction) external; /** * @notice Create an auction that mints an edition being auctioned into escrow (mints the next NFT on the edition) * @param auctionId ID of auction * @param auction The auction details */ function createAuctionForNewEdition( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction, uint256 editionId ) external; /** * @notice Create an auction for an existing NFT * @param auctionId ID of auction * @param auction The auction details */ function createAuctionForExistingToken(bytes32 auctionId, EnglishAuction memory auction) external; /** * @notice Create an auction for an existing NFT, with atomic transfer approval meta-tx packets * @param auctionId ID of auction * @param auction The auction details * @param req The request containing the call to transfer the auctioned NFT into escrow * @param requestSignature The signed request */ function createAuctionForExistingTokenWithMetaTxPacket( bytes32 auctionId, IAuctionManager.EnglishAuction memory auction, IMinimalForwarder.ForwardRequest calldata req, bytes calldata requestSignature ) external; /** * @notice Update the payment recipient for an auction * @param auctionId ID of auction being updated * @param newPaymentRecipient New payment recipient on the auction */ function updatePaymentRecipient(bytes32 auctionId, address payable newPaymentRecipient) external; /** * @notice Update the preferred nft recipient of a bid * @param auctionId ID of auction being updated * @param newPreferredNFTRecipient New nft recipient on the auction bid */ function updatePreferredNFTRecipient(bytes32 auctionId, address newPreferredNFTRecipient) external; /** * @notice Makes a bid on an auction * @param claim Claim needed to make the bid * @param claimSignature Claim signature to be unwrapped and validated * @param preferredNftRecipient Bidder's preferred recipient of NFT if they win auction */ function bid( IAuctionManager.Claim calldata claim, bytes calldata claimSignature, address preferredNftRecipient ) external payable; /** * @notice Fulfill auction and disperse winning bid / auctioned NFT. * @dev Anyone can call this function * @param auctionId ID of auction to fulfill */ function fulfillAuction(bytes32 auctionId) external; /** * @notice "Cancels" an auction on-chain, if a valid bid hasn't been made yet. Transfers NFT back to auction owner * @param auctionId ID of auction being "cancelled" */ function cancelAuctionOnChain(bytes32 auctionId) external; /** * @notice Updates the platform account receiving a portion of winning bids * @param newPlatform New account to receive portion */ function updatePlatform(address payable newPlatform) external; /** * @notice Updates the platform cut * @param newCutBPS New account to receive portion */ function updatePlatformCut(uint256 newCutBPS) external; /** * @notice Update an auction's end time before first valid bid is made on auction * @param auctionId Auction ID * @param newEndTime New end time */ function updateEndTime(bytes32 auctionId, uint256 newEndTime) external; /** * @notice Verifies the validity of a claim, simulating call to bid() * @param claim Claim needed to make the bid * @param claimSignature Claim signature to be unwrapped and validated * @param expectedMsgSender Expected msg.sender when bid() is called, that is being simulated */ function verifyClaim( Claim calldata claim, bytes calldata claimSignature, address expectedMsgSender ) external view returns (bool); /** * @notice Get all data about an auction except for number of bids made per user * @param auctionId ID of auction */ function getFullAuctionData( bytes32 auctionId ) external view returns (EnglishAuction memory, HighestBidderData memory, EditionAuction memory); /** * @notice Get all data about a set of auctions except for number of bids made per user * @param auctionIds IDs of auctions */ function getFullAuctionsData( bytes32[] calldata auctionIds ) external view returns (EnglishAuction[] memory, HighestBidderData[] memory, EditionAuction[] memory); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @notice Used to interface with EditionsMetadataRenderer * @author highlight.xyz */ interface IEditionsMetadataRenderer { /** * @notice Token edition info * @param name Edition name * @param description Edition description * @param imageUrl Edition image url * @param animationUrl Edition animation url * @param externalUrl Edition external url * @param attributes Edition attributes */ struct TokenEditionInfo { string name; string description; string imageUrl; string animationUrl; string externalUrl; string attributes; } /** * @notice Updates name on edition. Managed by token manager if existent * @param editionsAddress Address of collection that edition is on * @param editionId ID of edition to update * @param name New name of edition */ function updateName(address editionsAddress, uint256 editionId, string calldata name) external; /** * @notice Updates description on edition. Managed by token manager if existent * @param editionsAddress Address of collection that edition is on * @param editionId ID of edition to update * @param description New description of edition */ function updateDescription(address editionsAddress, uint256 editionId, string calldata description) external; /** * @notice Updates imageUrl on edition. Managed by token manager if existent * @param editionsAddress Address of collection that edition is on * @param editionId ID of edition to update * @param imageUrl New imageUrl of edition */ function updateImageUrl(address editionsAddress, uint256 editionId, string calldata imageUrl) external; /** * @notice Updates animationUrl on edition. Managed by token manager if existent * @param editionsAddress Address of collection that edition is on * @param editionId ID of edition to update * @param animationUrl New animationUrl of edition */ function updateAnimationUrl(address editionsAddress, uint256 editionId, string calldata animationUrl) external; /** * @notice Updates externalUrl on edition. Managed by token manager if existent * @param editionsAddress Address of collection that edition is on * @param editionId ID of edition to update * @param externalUrl New externalUrl of edition */ function updateExternalUrl(address editionsAddress, uint256 editionId, string calldata externalUrl) external; /** * @notice Updates attributes on edition. Managed by token manager if existent * @param editionsAddress Address of collection that edition is on * @param editionId ID of edition to update * @param attributes New attributes of edition */ function updateAttributes(address editionsAddress, uint256 editionId, string calldata attributes) external; /** * @notice Updates any set of metadata fields * @param editionsAddress Address of collection that edition is on * @param editionId ID of edition to update * @param tokenEditionInfo New metadata fields * @param updateIds Encoded what metadata fields to update */ function updateMetadata( address editionsAddress, uint256 editionId, TokenEditionInfo calldata tokenEditionInfo, uint256[] calldata updateIds ) external; /** * @notice Get an edition's uri. HAS to be called by collection * @param editionId Edition's id to get uri for */ function editionURI(uint256 editionId) external view returns (string memory); /** * @notice Get an edition's info. * @param editionsAddress Address of collection that edition is on * @param editionsId Edition's id to get info for */ function editionInfo(address editionsAddress, uint256 editionsId) external view returns (TokenEditionInfo memory); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @notice Interfaces with the details of editions on collections * @author highlight.xyz */ interface IEditionCollection { /** * @notice Edition details * @param name Edition name * @param size Edition size * @param supply Total number of tokens minted on edition * @param initialTokenId Token id of first token minted in edition */ struct EditionDetails { string name; uint256 size; uint256 supply; uint256 initialTokenId; } /** * @notice Get the edition a token belongs to * @param tokenId The token id of the token */ function getEditionId(uint256 tokenId) external view returns (uint256); /** * @notice Get an edition's details * @param editionId Edition id */ function getEditionDetails(uint256 editionId) external view returns (EditionDetails memory); /** * @notice Get the details and uris of a number of editions * @param editionIds List of editions to get info for */ function getEditionsDetailsAndUri( uint256[] calldata editionIds ) external view returns (EditionDetails[] memory, string[] memory uris); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; /** * @author highlight.xyz * @notice If token managers implement this, transfer actions will call * postSafeTransferFrom or postTransferFrom on the token manager. */ interface IPostTransfer { /** * @notice Hook called by community after safe transfers, if token manager of transferred token implements this * interface. * @param operator Operator transferring tokens * @param from Token(s) sender * @param to Token(s) recipient * @param id Transferred token's id * @param data Arbitrary data */ function postSafeTransferFrom(address operator, address from, address to, uint256 id, bytes memory data) external; /** * @notice Hook called by community after transfers, if token manager of transferred token implements * this interface. * @param operator Operator transferring tokens * @param from Token(s) sender * @param to Token(s) recipient * @param id Transferred token's id */ function postTransferFrom(address operator, address from, address to, uint256 id) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "./ITokenManager.sol"; /** * @title ITokenManager * @author highlight.xyz * @notice Enables interfacing with custom token managers for editions contracts */ interface ITokenManagerEditions is ITokenManager { /** * @notice The updated field in metadata updates */ enum FieldUpdated { name, description, imageUrl, animationUrl, externalUrl, attributes, other } /** * @notice Returns whether metadata updater is allowed to update * @param editionsAddress Address of editions contract * @param sender Updater * @param editionId Token/edition who's uri is being updated * If id is 0, implementation should decide behaviour for base uri update * @param newData Token's new uri if called by general contract, and any metadata field if called by editions * @param fieldUpdated Which metadata field was updated * @return If invocation can update metadata */ function canUpdateEditionsMetadata( address editionsAddress, address sender, uint256 editionId, bytes calldata newData, FieldUpdated fieldUpdated ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; /** * @author highlight.xyz * @notice If token managers implement this, transfer actions will call * postBurn on the token manager. */ interface IPostBurn { /** * @notice Hook called by contract after burn, if token manager of burned token implements this * interface. * @param operator Operator burning tokens * @param sender Msg sender * @param id Burned token's id or id of edition of token that is burned */ function postBurn(address operator, address sender, uint256 id) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @notice Mint interface on editions contracts * @author highlight.xyz */ interface IERC721EditionMint { /** * @notice Mints one NFT to one recipient * @param editionId Edition to mint the NFT on * @param recipient Recipient of minted NFT */ function mintOneToRecipient(uint256 editionId, address recipient) external returns (uint256); /** * @notice Mints an amount of NFTs to one recipient * @param editionId Edition to mint the NFTs on * @param recipient Recipient of minted NFTs * @param amount Amount of NFTs minted */ function mintAmountToRecipient(uint256 editionId, address recipient, uint256 amount) external returns (uint256); /** * @notice Mints one NFT each to a number of recipients * @param editionId Edition to mint the NFTs on * @param recipients Recipients of minted NFTs */ function mintOneToRecipients(uint256 editionId, address[] memory recipients) external returns (uint256); /** * @notice Mints an amount of NFTs each to a number of recipients * @param editionId Edition to mint the NFTs on * @param recipients Recipients of minted NFTs * @param amount Amount of NFTs minted per recipient */ function mintAmountToRecipients( uint256 editionId, address[] memory recipients, uint256 amount ) external returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @title MintManager interface for onchain abridged mint vectors * @author highlight.xyz */ interface IAbridgedMintVector { /** * @notice On-chain mint vector (stored data) * @param contractAddress NFT smart contract address * @param startTimestamp When minting opens on vector * @param endTimestamp When minting ends on vector * @param paymentRecipient Payment recipient * @param maxTotalClaimableViaVector Max number of tokens that can be minted via vector * @param totalClaimedViaVector Total number of tokens minted via vector * @param currency Currency used for payment. Native gas token, if zero address * @param tokenLimitPerTx Max number of tokens that can be minted in one transaction * @param maxUserClaimableViaVector Max number of tokens that can be minted by user via vector * @param pricePerToken Price that has to be paid per minted token * @param editionId Edition ID, if vector is for edition based collection * @param editionBasedCollection If vector is for an edition based collection * @param requireDirectEOA Require minters to directly be EOAs * @param allowlistRoot Root of merkle tree with allowlist */ struct AbridgedVectorData { uint160 contractAddress; uint48 startTimestamp; uint48 endTimestamp; uint160 paymentRecipient; uint48 maxTotalClaimableViaVector; uint48 totalClaimedViaVector; uint160 currency; uint48 tokenLimitPerTx; uint48 maxUserClaimableViaVector; uint192 pricePerToken; uint48 editionId; bool editionBasedCollection; bool requireDirectEOA; bytes32 allowlistRoot; } /** * @notice On-chain mint vector (public) - See {AbridgedVectorData} */ struct AbridgedVector { address contractAddress; uint48 startTimestamp; uint48 endTimestamp; address paymentRecipient; uint48 maxTotalClaimableViaVector; uint48 totalClaimedViaVector; address currency; uint48 tokenLimitPerTx; uint48 maxUserClaimableViaVector; uint192 pricePerToken; uint48 editionId; bool editionBasedCollection; bool requireDirectEOA; bytes32 allowlistRoot; } /** * @notice Config defining what fields to update * @param updateStartTimestamp If 1, update startTimestamp * @param updateEndTimestamp If 1, update endTimestamp * @param updatePaymentRecipient If 1, update paymentRecipient * @param updateMaxTotalClaimableViaVector If 1, update maxTotalClaimableViaVector * @param updateTokenLimitPerTx If 1, update tokenLimitPerTx * @param updateMaxUserClaimableViaVector If 1, update maxUserClaimableViaVector * @param updatePricePerToken If 1, update pricePerToken * @param updateCurrency If 1, update currency * @param updateRequireDirectEOA If 1, update requireDirectEOA * @param updateMetadata If 1, update MintVector metadata */ struct UpdateAbridgedVectorConfig { uint16 updateStartTimestamp; uint16 updateEndTimestamp; uint16 updatePaymentRecipient; uint16 updateMaxTotalClaimableViaVector; uint16 updateTokenLimitPerTx; uint16 updateMaxUserClaimableViaVector; uint8 updatePricePerToken; uint8 updateCurrency; uint8 updateRequireDirectEOA; uint8 updateMetadata; } /** * @notice Creates on-chain vector * @param _vector Vector to create */ function createAbridgedVector(AbridgedVectorData memory _vector) external; /** * @notice Updates on-chain vector * @param vectorId ID of vector to update * @param _newVector New vector details * @param updateConfig Number encoding what fields to update * @param pause Pause / unpause vector * @param flexibleData Flexible data in vector metadata */ function updateAbridgedVector( uint256 vectorId, AbridgedVector calldata _newVector, UpdateAbridgedVectorConfig calldata updateConfig, bool pause, uint128 flexibleData ) external; /** * @notice Pauses or unpauses an on-chain mint vector * @param vectorId ID of abridged vector to pause * @param pause True to pause, False to unpause * @param flexibleData Flexible data that can be interpreted differently */ function setAbridgedVectorMetadata(uint256 vectorId, bool pause, uint128 flexibleData) external; /** * @notice Get on-chain abridged vector * @param vectorId ID of abridged vector to get */ function getAbridgedVector(uint256 vectorId) external view returns (AbridgedVector memory); /** * @notice Get on-chain abridged vector metadata * @param vectorId ID of abridged vector to get */ function getAbridgedVectorMetadata(uint256 vectorId) external view returns (bool, uint128); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "../royaltyManager/interfaces/IRoyaltyManager.sol"; import "../tokenManager/interfaces/ITokenManager.sol"; import "../utils/Ownable.sol"; import "../utils/ERC2981/IERC2981Upgradeable.sol"; import "../utils/ERC165/ERC165CheckerUpgradeable.sol"; import "../metatx/ERC2771ContextUpgradeable.sol"; import "../observability/IObservabilityV2.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import { UUPSUpgradeable } from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; /** * @title Base ERC1155 * @author highlight.xyz * @notice Core piece of Highlight NFT contracts (v2) */ abstract contract ERC1155Base is OwnableUpgradeable, IERC2981Upgradeable, ERC2771ContextUpgradeable, ReentrancyGuardUpgradeable, UUPSUpgradeable { using EnumerableSet for EnumerableSet.AddressSet; using ERC165CheckerUpgradeable for address; /** * @notice Throw when token or royalty manager is invalid */ error InvalidManager(); /** * @notice Throw when token or royalty manager does not exist */ error ManagerDoesNotExist(); /** * @notice Throw when sender is unauthorized to perform action */ error Unauthorized(); /** * @notice Throw when sender is not a minter */ error NotMinter(); /** * @notice Throw when token manager or royalty manager swap is blocked */ error ManagerSwapBlocked(); /** * @notice Throw when token manager or royalty manager remove is blocked */ error ManagerRemoveBlocked(); /** * @notice Throw when setting default or granular royalty is blocked */ error RoyaltySetBlocked(); /** * @notice Throw when royalty BPS is invalid */ error RoyaltyBPSInvalid(); /** * @notice Throw when minter registration is invalid */ error MinterRegistrationInvalid(); /** * @notice Set of minters allowed to mint on contract */ EnumerableSet.AddressSet internal _minters; /** * @notice Global token/edition manager default */ address public defaultManager; /** * @notice Token managers per token. 1155 token id. */ mapping(uint256 => address) internal _managers; /** * @notice Default royalty for entire contract */ IRoyaltyManager.Royalty internal _defaultRoyalty; /** * @notice Royalty per token. 1155 token id. */ mapping(uint256 => IRoyaltyManager.Royalty) internal _royalties; /** * @notice Royalty manager - optional contract that defines the conditions around setting royalties */ address public royaltyManager; /** * @notice Freezes minting on smart contract forever */ uint8 internal _mintFrozen; /** * @notice Observability contract */ IObservabilityV2 public observability; /** * @notice Emitted when minter is registered or unregistered * @param minter Minter that was changed * @param registered True if the minter was registered, false if unregistered */ event MinterRegistrationChanged(address indexed minter, bool indexed registered); /** * @notice Emitted when token managers are set for token/edition ids * @param _ids token ids * @param _tokenManagers Token managers to set for tokens / editions */ event GranularTokenManagersSet(uint256[] _ids, address[] _tokenManagers); /** * @notice Emitted when token managers are removed for token/edition ids * @param _ids token ids to remove token managers for */ event GranularTokenManagersRemoved(uint256[] _ids); /** * @notice Emitted when default token manager changed * @param newDefaultTokenManager New default token manager. Zero address if old one was removed */ event DefaultTokenManagerChanged(address indexed newDefaultTokenManager); /** * @notice Emitted when default royalty is set * @param recipientAddress Royalty recipient * @param royaltyPercentageBPS Percentage of sale (in basis points) owed to royalty recipient */ event DefaultRoyaltySet(address indexed recipientAddress, uint16 indexed royaltyPercentageBPS); /** * @notice Emitted when royalties are set for token ids * @param ids Token ids * @param _newRoyalties New royalties for each token */ event GranularRoyaltiesSet(uint256[] ids, IRoyaltyManager.Royalty[] _newRoyalties); /** * @notice Emitted when royalty manager is updated * @param newRoyaltyManager New royalty manager. Zero address if old one was removed */ event RoyaltyManagerChanged(address indexed newRoyaltyManager); /** * @notice Emitted when mints are frozen permanently */ event MintsFrozen(); /** * @notice Restricts calls to minters */ modifier onlyMinter() { if (!_minters.contains(_msgSender())) { _revert(NotMinter.selector); } _; } /** * @notice Restricts calls if input royalty bps is over 10000 */ modifier royaltyValid(uint16 _royaltyBPS) { if (!_royaltyBPSValid(_royaltyBPS)) { _revert(RoyaltyBPSInvalid.selector); } _; } /** * @notice Registers a minter * @param minter New minter */ function registerMinter(address minter) external onlyOwner { if (!_minters.add(minter)) { _revert(MinterRegistrationInvalid.selector); } emit MinterRegistrationChanged(minter, true); observability.emitMinterRegistrationChanged(minter, true); } /** * @notice Unregisters a minter * @param minter Minter to unregister */ function unregisterMinter(address minter) external onlyOwner { if (!_minters.remove(minter)) { _revert(MinterRegistrationInvalid.selector); } emit MinterRegistrationChanged(minter, false); observability.emitMinterRegistrationChanged(minter, false); } /** * @notice Sets granular token managers if current token manager(s) allow it * @param _ids Token ids * @param _tokenManagers Token managers to set for tokens / editions */ function setGranularTokenManagers( uint256[] calldata _ids, address[] calldata _tokenManagers ) external nonReentrant { address msgSender = _msgSender(); address tempOwner = owner(); uint256 idsLength = _ids.length; for (uint256 i = 0; i < idsLength; i++) { if (!_isValidTokenManager(_tokenManagers[i])) { _revert(InvalidManager.selector); } address currentTokenManager = tokenManager(_ids[i]); if (currentTokenManager == address(0)) { if (msgSender != tempOwner) { _revert(Unauthorized.selector); } } else { if (!ITokenManager(currentTokenManager).canSwap(msgSender, _ids[i], _managers[i])) { _revert(ManagerSwapBlocked.selector); } } _managers[_ids[i]] = _tokenManagers[i]; } emit GranularTokenManagersSet(_ids, _tokenManagers); observability.emitGranularTokenManagersSet(_ids, _tokenManagers); } /** * @notice Remove granular token managers * @param _ids Token ids to remove token managers for */ function removeGranularTokenManagers(uint256[] calldata _ids) external nonReentrant { address msgSender = _msgSender(); uint256 idsLength = _ids.length; for (uint256 i = 0; i < idsLength; i++) { address currentTokenManager = _managers[_ids[i]]; if (currentTokenManager == address(0)) { _revert(ManagerDoesNotExist.selector); } if (!ITokenManager(currentTokenManager).canRemoveItself(msgSender, _ids[i])) { _revert(ManagerRemoveBlocked.selector); } _managers[_ids[i]] = address(0); } emit GranularTokenManagersRemoved(_ids); observability.emitGranularTokenManagersRemoved(_ids); } /** * @notice Set default token manager if current token manager allows it * @param _defaultTokenManager New default token manager */ function setDefaultTokenManager(address _defaultTokenManager) external nonReentrant { if (!_isValidTokenManager(_defaultTokenManager)) { _revert(InvalidManager.selector); } address msgSender = _msgSender(); address currentTokenManager = defaultManager; if (currentTokenManager == address(0)) { if (msgSender != owner()) { _revert(Unauthorized.selector); } } else { if (!ITokenManager(currentTokenManager).canSwap(msgSender, 0, _defaultTokenManager)) { _revert(ManagerSwapBlocked.selector); } } defaultManager = _defaultTokenManager; emit DefaultTokenManagerChanged(_defaultTokenManager); observability.emitDefaultTokenManagerChanged(_defaultTokenManager); } /** * @notice Removes default token manager if current token manager allows it */ function removeDefaultTokenManager() external nonReentrant { address msgSender = _msgSender(); address currentTokenManager = defaultManager; if (currentTokenManager == address(0)) { _revert(ManagerDoesNotExist.selector); } if (!ITokenManager(currentTokenManager).canRemoveItself(msgSender, 0)) { _revert(ManagerRemoveBlocked.selector); } defaultManager = address(0); emit DefaultTokenManagerChanged(address(0)); observability.emitDefaultTokenManagerChanged(address(0)); } /** * @notice Sets default royalty if royalty manager allows it * @param _royalty New default royalty */ function setDefaultRoyalty( IRoyaltyManager.Royalty calldata _royalty ) external nonReentrant royaltyValid(_royalty.royaltyPercentageBPS) { address msgSender = _msgSender(); address _royaltyManager = royaltyManager; if (_royaltyManager == address(0)) { if (msgSender != owner()) { _revert(Unauthorized.selector); } } else { if (!IRoyaltyManager(_royaltyManager).canSetDefaultRoyalty(_royalty, msgSender)) { _revert(RoyaltySetBlocked.selector); } } _defaultRoyalty = _royalty; emit DefaultRoyaltySet(_royalty.recipientAddress, _royalty.royaltyPercentageBPS); observability.emitDefaultRoyaltySet(_royalty.recipientAddress, _royalty.royaltyPercentageBPS); } /** * @notice Sets granular royalties (per token) if royalty manager allows it * @param ids Token ids * @param _newRoyalties New royalties for each token */ function setGranularRoyalties( uint256[] calldata ids, IRoyaltyManager.Royalty[] calldata _newRoyalties ) external nonReentrant { address msgSender = _msgSender(); address tempOwner = owner(); address _royaltyManager = royaltyManager; uint256 idsLength = ids.length; if (_royaltyManager == address(0)) { if (msgSender != tempOwner) { _revert(Unauthorized.selector); } for (uint256 i = 0; i < idsLength; i++) { if (!_royaltyBPSValid(_newRoyalties[i].royaltyPercentageBPS)) { _revert(RoyaltyBPSInvalid.selector); } _royalties[ids[i]] = _newRoyalties[i]; } } else { for (uint256 i = 0; i < idsLength; i++) { if (!_royaltyBPSValid(_newRoyalties[i].royaltyPercentageBPS)) { _revert(RoyaltyBPSInvalid.selector); } if (!IRoyaltyManager(_royaltyManager).canSetGranularRoyalty(ids[i], _newRoyalties[i], msgSender)) { _revert(RoyaltySetBlocked.selector); } _royalties[ids[i]] = _newRoyalties[i]; } } emit GranularRoyaltiesSet(ids, _newRoyalties); observability.emitGranularRoyaltiesSet(ids, _newRoyalties); } /** * @notice Sets royalty manager if current one allows it * @param _royaltyManager New royalty manager */ function setRoyaltyManager(address _royaltyManager) external nonReentrant { if (!_isValidRoyaltyManager(_royaltyManager)) { _revert(InvalidManager.selector); } address msgSender = _msgSender(); address currentRoyaltyManager = royaltyManager; if (currentRoyaltyManager == address(0)) { if (msgSender != owner()) { _revert(Unauthorized.selector); } } else { if (!IRoyaltyManager(currentRoyaltyManager).canSwap(_royaltyManager, msgSender)) { _revert(ManagerSwapBlocked.selector); } } royaltyManager = _royaltyManager; emit RoyaltyManagerChanged(_royaltyManager); observability.emitRoyaltyManagerChanged(_royaltyManager); } /** * @notice Removes royalty manager if current one allows it */ function removeRoyaltyManager() external nonReentrant { address msgSender = _msgSender(); address currentRoyaltyManager = royaltyManager; if (currentRoyaltyManager == address(0)) { _revert(ManagerDoesNotExist.selector); } if (!IRoyaltyManager(currentRoyaltyManager).canRemoveItself(msgSender)) { _revert(ManagerRemoveBlocked.selector); } royaltyManager = address(0); emit RoyaltyManagerChanged(address(0)); observability.emitRoyaltyManagerChanged(address(0)); } /** * @notice Freeze mints on contract forever */ function freezeMints() external onlyOwner nonReentrant { _mintFrozen = 1; emit MintsFrozen(); observability.emitMintsFrozen(); } /** * @notice Return allowed minters on contract */ function minters() external view returns (address[] memory) { return _minters.values(); } /** * @notice Conforms to ERC-2981. Editions should overwrite to return royalty for entire edition * @param _tokenId Token id * @param _salePrice Sale price of token */ function royaltyInfo( uint256 _tokenId, uint256 _salePrice ) public view virtual override returns (address receiver, uint256 royaltyAmount) { IRoyaltyManager.Royalty memory royalty = _royalties[_tokenId]; if (royalty.recipientAddress == address(0)) { royalty = _defaultRoyalty; } receiver = royalty.recipientAddress; royaltyAmount = (_salePrice * uint256(royalty.royaltyPercentageBPS)) / 10000; } /** * @notice Returns the token manager for the id passed in. * @param id Token ID */ function tokenManager(uint256 id) public view returns (address manager) { manager = defaultManager; address granularManager = _managers[id]; if (granularManager != address(0)) { manager = granularManager; } } /** * @notice Initializes the contract, setting the creator as the initial owner. * @param _creator Contract creator * @param defaultRoyalty Default royalty for the contract * @param _defaultTokenManager Default token manager for the contract */ function __ERC1155Base_initialize( address _creator, IRoyaltyManager.Royalty memory defaultRoyalty, address _defaultTokenManager ) internal onlyInitializing royaltyValid(defaultRoyalty.royaltyPercentageBPS) { __Ownable_init(); __ReentrancyGuard_init(); _transferOwnership(_creator); if (defaultRoyalty.recipientAddress != address(0)) { _defaultRoyalty = defaultRoyalty; } if (_defaultTokenManager != address(0)) { defaultManager = _defaultTokenManager; } } /** * @notice See {UUPSUpgradeable-_authorizeUpgrade} * @param // New implementation to upgrade to */ function _authorizeUpgrade(address) internal override { revert("Not upgradeable"); } /** * @notice Returns true if address is a valid tokenManager * @param _tokenManager Token manager being checked */ function _isValidTokenManager(address _tokenManager) internal view returns (bool) { return _tokenManager.supportsInterface(type(ITokenManager).interfaceId); } /** * @notice Returns true if address is a valid royaltyManager * @param _royaltyManager Royalty manager being checked */ function _isValidRoyaltyManager(address _royaltyManager) internal view returns (bool) { return _royaltyManager.supportsInterface(type(IRoyaltyManager).interfaceId); } /** * @notice Used for meta-transactions */ function _msgSender() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (address sender) { return ERC2771ContextUpgradeable._msgSender(); } /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure virtual { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } /** * @notice Used for meta-transactions */ function _msgData() internal view virtual override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (bytes calldata) { return ERC2771ContextUpgradeable._msgData(); } /** * @notice Returns true if royalty bps passed in is valid (<= 10000) * @param _royaltyBPS Royalty basis points */ function _royaltyBPSValid(uint16 _royaltyBPS) private pure returns (bool) { return _royaltyBPS <= 10000; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "../../royaltyManager/interfaces/IRoyaltyManager.sol"; /** * @notice Core creation interface (1155s) * @author highlight.xyz */ interface IERC1155EditionsDFS { /** * @notice Create an edition * @param _editionUri Edition uri (metadata) * @param _editionSize Edition size * @param _editionTokenManager Token manager for edition * @param editionRoyalty Edition's royalty */ function createEdition( string memory _editionUri, uint256 _editionSize, address _editionTokenManager, IRoyaltyManager.Royalty memory editionRoyalty, bytes calldata mintVectorData ) external returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; interface IERC1155Standard { /** * @notice Return Highlight contract standard hash */ function highlightContractStandardHash() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/ERC1155.sol) pragma solidity 0.8.10; import "./IERC1155Upgradeable.sol"; import "./IERC1155ReceiverUpgradeable.sol"; import "./IERC1155MetadataURIUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol"; import "../ERC165/ERC165Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /** * @dev Implementation of the basic standard multi-token. * See https://eips.ethereum.org/EIPS/eip-1155 * Originally based on code by Enjin: https://github.com/enjin/erc-1155 * * _Available since v3.1._ */ contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable { using AddressUpgradeable for address; /** * @notice ERC1155 errors */ error InvalidOwner(); error InvalidInput(); error NotTokenOwnerOrApproved(); error TransferToZeroAddress(); error TransferFromZeroAddress(); error InsufficientBalance(); error InvalidOperator(); error ReceiverRejectedTokens(); error ReceiverNonImplementer(); // Mapping from token ID to account balances mapping(uint256 => mapping(address => uint256)) private _balances; // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1155Upgradeable).interfaceId || interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC1155MetadataURI-uri}. * * This implementation returns the same URI for *all* token types. It relies * on the token type ID substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * Clients calling this function must replace the `\{id\}` substring with the * actual token type ID. */ function uri(uint256) public view virtual override returns (string memory) { return ""; } /** * @dev See {IERC1155-balanceOf}. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { if (account == address(0)) { _revert(InvalidOwner.selector); } return _balances[id][account]; } /** * @dev See {IERC1155-balanceOfBatch}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] memory accounts, uint256[] memory ids ) public view virtual override returns (uint256[] memory) { if (accounts.length != ids.length) { _revert(InvalidInput.selector); } uint256[] memory batchBalances = new uint256[](accounts.length); for (uint256 i = 0; i < accounts.length; ++i) { batchBalances[i] = balanceOf(accounts[i], ids[i]); } return batchBalances; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return _operatorApprovals[account][operator]; } /** * @dev See {IERC1155-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { if (!(from == _msgSender() || isApprovedForAll(from, _msgSender()))) { _revert(NotTokenOwnerOrApproved.selector); } _safeTransferFrom(from, to, id, amount, data); } /** * @dev See {IERC1155-safeBatchTransferFrom}. */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { if (!(from == _msgSender() || isApprovedForAll(from, _msgSender()))) { _revert(NotTokenOwnerOrApproved.selector); } _safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { if (to == address(0)) { _revert(TransferToZeroAddress.selector); } address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { _revert(InsufficientBalance.selector); } unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; emit TransferSingle(operator, from, to, id, amount); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { if (ids.length != amounts.length) { _revert(InvalidInput.selector); } if (to == address(0)) { _revert(TransferToZeroAddress.selector); } address operator = _msgSender(); for (uint256 i = 0; i < ids.length; ++i) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { _revert(InsufficientBalance.selector); } unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; } emit TransferBatch(operator, from, to, ids, amounts); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); } /** * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual { if (to == address(0)) { _revert(TransferToZeroAddress.selector); } address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _balances[id][to] += amount; emit TransferSingle(operator, address(0), to, id, amount); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _mintBatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { if (to == address(0)) { _revert(TransferToZeroAddress.selector); } if (ids.length != amounts.length) { _revert(InvalidInput.selector); } address operator = _msgSender(); for (uint256 i = 0; i < ids.length; i++) { _balances[ids[i]][to] += amounts[i]; } emit TransferBatch(operator, address(0), to, ids, amounts); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); } /** * @dev Destroys `amount` tokens of token type `id` from `from` * * Emits a {TransferSingle} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have at least `amount` tokens of token type `id`. */ function _burn(address from, uint256 id, uint256 amount) internal virtual { if (from == address(0)) { _revert(TransferFromZeroAddress.selector); } address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { _revert(InsufficientBalance.selector); } unchecked { _balances[id][from] = fromBalance - amount; } emit TransferSingle(operator, from, address(0), id, amount); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. */ function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual { if (from == address(0)) { _revert(TransferFromZeroAddress.selector); } if (ids.length != amounts.length) { _revert(InvalidInput.selector); } address operator = _msgSender(); for (uint256 i = 0; i < ids.length; i++) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { _revert(InsufficientBalance.selector); } unchecked { _balances[id][from] = fromBalance - amount; } } emit TransferBatch(operator, from, address(0), ids, amounts); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { if (owner == operator) { _revert(InvalidOperator.selector); } _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Hook that is called after any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `id` and `amount` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /** * @dev For more efficient reverts. */ function _revert(bytes4 errorSelector) internal pure virtual { assembly { mstore(0x00, errorSelector) revert(0x00, 0x04) } } function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns ( bytes4 response ) { if (response != IERC1155ReceiverUpgradeable.onERC1155Received.selector) { _revert(ReceiverRejectedTokens.selector); } } catch Error(string memory reason) { revert(reason); } catch { _revert(ReceiverNonImplementer.selector); } } } function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response ) { if (response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector) { _revert(ReceiverRejectedTokens.selector); } } catch Error(string memory reason) { revert(reason); } catch { _revert(ReceiverNonImplementer.selector); } } } function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { uint256[] memory array = new uint256[](1); array[0] = element; return array; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[47] private __gap; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "./IMechanicData.sol"; /** * @notice Capabilities on MintManager pertaining to mechanics */ interface IMechanicMintManager is IMechanicData { /** * @notice Register a new mechanic vector * @param _mechanicVectorMetadata Mechanic vector metadata * @param seed Used to seed uniqueness into mechanic vector ID generation * @param vectorData Vector data to store on mechanic (optional) */ function registerMechanicVector( MechanicVectorMetadata calldata _mechanicVectorMetadata, uint96 seed, bytes calldata vectorData ) external; /** * @notice Pause or unpause a mechanic vector * @param mechanicVectorId Global mechanic ID * @param pause If true, pause the mechanic mint vector. If false, unpause */ function setPauseOnMechanicMintVector(bytes32 mechanicVectorId, bool pause) external; /** * @notice Mint a number of tokens sequentially via a mechanic vector * @param mechanicVectorId Global mechanic ID * @param recipient Mint recipient * @param numToMint Number of tokens to mint * @param data Custom data to be processed by mechanic */ function mechanicMintNum( bytes32 mechanicVectorId, address recipient, uint32 numToMint, bytes calldata data ) external payable; /** * @notice Mint a specific set of token ids via a mechanic vector * @param mechanicVectorId Global mechanic ID * @param recipient Mint recipient * @param tokenIds IDs of tokens to mint * @param data Custom data to be processed by mechanic */ function mechanicMintChoose( bytes32 mechanicVectorId, address recipient, uint256[] calldata tokenIds, bytes calldata data ) external payable; }
// SPDX-License-Identifier: Unlicensed pragma solidity 0.8.10; /** * @title Minimal forwarder interface * @author highlight.xyz */ interface IMinimalForwarder { struct ForwardRequest { address from; address to; uint256 value; uint256 gas; uint256 nonce; bytes data; } function execute( ForwardRequest calldata req, bytes calldata signature ) external payable returns (bool, bytes memory); function getNonce(address from) external view returns (uint256); function verify(ForwardRequest calldata req, bytes calldata signature) external view returns (bool); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @title ITokenManager * @author highlight.xyz * @notice Enables interfacing with custom token managers */ interface ITokenManager { /** * @notice Returns whether metadata updater is allowed to update * @param sender Updater * @param id Token/edition who's uri is being updated * If id is 0, implementation should decide behaviour for base uri update * @param newData Token's new uri if called by general contract, and any metadata field if called by editions * @return If invocation can update metadata */ function canUpdateMetadata(address sender, uint256 id, bytes calldata newData) external returns (bool); /** * @notice Returns whether token manager can be swapped for another one by invocator * @notice Default token manager implementations should ignore id * @param sender Swapper * @param id Token grouping id (token id or edition id) * @param newTokenManager New token manager being swapped to * @return If invocation can swap token managers */ function canSwap(address sender, uint256 id, address newTokenManager) external returns (bool); /** * @notice Returns whether token manager can be removed * @notice Default token manager implementations should ignore id * @param sender Swapper * @param id Token grouping id (token id or edition id) * @return If invocation can remove token manager */ function canRemoveItself(address sender, uint256 id) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (metatx/ERC2771Context.sol) pragma solidity 0.8.10; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /** * @dev Context variant with ERC2771 support. * Openzeppelin contract slightly modified by ishan@ highlight.xyz to be upgradeable. */ abstract contract ERC2771ContextUpgradeable is Initializable { address private _trustedForwarder; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; function isTrustedForwarder(address forwarder) public view virtual returns (bool) { return forwarder == _trustedForwarder; } function __ERC2771ContextUpgradeable__init__(address trustedForwarder) internal onlyInitializing { _trustedForwarder = trustedForwarder; } function _msgSender() internal view virtual returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. /* solhint-disable no-inline-assembly */ assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } /* solhint-enable no-inline-assembly */ } else { return msg.sender; } } function _msgData() internal view virtual returns (bytes calldata) { if (isTrustedForwarder(msg.sender)) { return msg.data[:msg.data.length - 20]; } else { return msg.data; } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "./IObservability.sol"; /** * @title IObservabilityV2 * @author highlight.xyz * @notice Interface to interact with the Highlight observabilityV2 singleton * @dev Singleton to coalesce select Highlight protocol events */ interface IObservabilityV2 is IObservability { /************************** Deployment events **************************/ /** * @notice Emitted when Editions1155 contract is deployed * @param deployer Contract deployer * @param contractAddress Address of contract that was deployed */ event Editions1155Deployed(address indexed deployer, address indexed contractAddress); /************************** ERC1155 events **************************/ /** * @notice Emitted when an amount `value` of `tokenId` token is transferred from `from` to `to` on contractAddress * @param contractAddress NFT contract token resides on * @param operator Transaction executor * @param from Token sender * @param to Token receiver * @param id ID of token being sent * @param value Amount of token ssent */ event TransferSingle( address indexed contractAddress, address operator, address indexed from, address indexed to, uint256 id, uint256 value ); /** * @notice Emitted when amount `values` of `tokenId` token is transferred from `from` to `to` on contractAddress * @param contractAddress NFT contract token resides on * @param operator Transaction executor * @param from Token sender * @param to Token receiver * @param ids Token ids being sent * @param values Amounts of tokens sent */ event TransferBatch( address indexed contractAddress, address operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @notice Emit Editions1155Deployed */ function emitEditions1155Deployed(address contractAddress) external; /** * @notice Emit 1155 TransferSingle */ function emitTransferSingle(address operator, address from, address to, uint256 tokenId, uint256 amount) external; /** * @notice Emit 1155 TransferBatch */ function emitTransferBatch( address operator, address from, address to, uint256[] calldata ids, uint256[] calldata amounts ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @title IRoyaltyManager * @author highlight.xyz * @notice Enables interfacing with custom royalty managers that define conditions on setting royalties for * NFT contracts */ interface IRoyaltyManager { /** * @notice Struct containing values required to adhere to ERC-2981 * @param recipientAddress Royalty recipient - can be EOA, royalty splitter contract, etc. * @param royaltyPercentageBPS Royalty cut, in basis points */ struct Royalty { address recipientAddress; uint16 royaltyPercentageBPS; } /** * @notice Defines conditions around being able to swap royalty manager for another one * @param newRoyaltyManager New royalty manager being swapped in * @param sender msg sender */ function canSwap(address newRoyaltyManager, address sender) external view returns (bool); /** * @notice Defines conditions around being able to remove current royalty manager * @param sender msg sender */ function canRemoveItself(address sender) external view returns (bool); /** * @notice Defines conditions around being able to set granular royalty (per token or per edition) * @param id Edition / token ID whose royalty is being set * @param royalty Royalty being set * @param sender msg sender */ function canSetGranularRoyalty(uint256 id, Royalty calldata royalty, address sender) external view returns (bool); /** * @notice Defines conditions around being able to set default royalty * @param royalty Royalty being set * @param sender msg sender */ function canSetDefaultRoyalty(Royalty calldata royalty, address sender) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Checker.sol) pragma solidity 0.8.10; import "./IERC165Upgradeable.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ /* solhint-disable */ library ERC165CheckerUpgradeable { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface, */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165Upgradeable).interfaceId) && !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces( address account, bytes4[] memory interfaceIds ) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in _interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * Interface identification is specified in ERC-165. */ function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeWithSelector(IERC165Upgradeable.supportsInterface.selector, interfaceId); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981Upgradeable.sol) pragma solidity 0.8.10; import "../ERC165/IERC165Upgradeable.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. * * _Available since v4.5._ */ interface IERC2981Upgradeable is IERC165Upgradeable { /** * @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 v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity 0.8.10; import "./IERC1155Upgradeable.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol) pragma solidity 0.8.10; import "../ERC165/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity 0.8.10; import "../ERC165/IERC165Upgradeable.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity 0.8.10; import "./IERC165Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ /* solhint-disable */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing {} function __ERC165_init_unchained() internal onlyInitializing {} /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; /** * @notice Defines a mechanic's metadata on the MintManager */ interface IMechanicData { /** * @notice A mechanic's metadata * @param contractAddress Collection contract address * @param editionId Edition ID if the collection is edition based * @param mechanic Address of mint mechanic contract * @param isEditionBased True if collection is edition based * @param isChoose True if collection uses a collector's choice mint paradigm * @param paused True if mechanic vector is paused */ struct MechanicVectorMetadata { address contractAddress; uint96 editionId; address mechanic; bool isEditionBased; bool isChoose; bool paused; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // 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; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _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; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.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. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. 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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } 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; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; import "./math/SignedMathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.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, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822.sol"; import "../ERC1967/ERC1967Upgrade.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade { /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeTo(address newImplementation) public virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. * * @custom:oz-upgrades-unsafe-allow-reachable delegatecall */ function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.10; import "../royaltyManager/interfaces/IRoyaltyManager.sol"; /** * @title IObservability * @author highlight.xyz * @notice Interface to interact with the Highlight observability singleton * @dev Singleton to coalesce select Highlight protocol events */ interface IObservability { /************************** ERC721Base / ERC721MinimizedBase events **************************/ /** * @notice Emitted when minter is registered or unregistered * @param contractAddress Initial contract that emitted event * @param minter Minter that was changed * @param registered True if the minter was registered, false if unregistered */ event MinterRegistrationChanged(address indexed contractAddress, address indexed minter, bool indexed registered); /** * @notice Emitted when token managers are set for token/edition ids * @param contractAddress Initial contract that emitted event * @param _ids Edition / token ids * @param _tokenManagers Token managers to set for tokens / editions */ event GranularTokenManagersSet(address indexed contractAddress, uint256[] _ids, address[] _tokenManagers); /** * @notice Emitted when token managers are removed for token/edition ids * @param contractAddress Initial contract that emitted event * @param _ids Edition / token ids to remove token managers for */ event GranularTokenManagersRemoved(address indexed contractAddress, uint256[] _ids); /** * @notice Emitted when default token manager changed * @param contractAddress Initial contract that emitted event * @param newDefaultTokenManager New default token manager. Zero address if old one was removed */ event DefaultTokenManagerChanged(address indexed contractAddress, address indexed newDefaultTokenManager); /** * @notice Emitted when default royalty is set * @param contractAddress Initial contract that emitted event * @param recipientAddress Royalty recipient * @param royaltyPercentageBPS Percentage of sale (in basis points) owed to royalty recipient */ event DefaultRoyaltySet( address indexed contractAddress, address indexed recipientAddress, uint16 indexed royaltyPercentageBPS ); /** * @notice Emitted when royalties are set for edition / token ids * @param contractAddress Initial contract that emitted event * @param ids Token / edition ids * @param _newRoyalties New royalties for each token / edition */ event GranularRoyaltiesSet(address indexed contractAddress, uint256[] ids, IRoyaltyManager.Royalty[] _newRoyalties); /** * @notice Emitted when royalty manager is updated * @param contractAddress Initial contract that emitted event * @param newRoyaltyManager New royalty manager. Zero address if old one was removed */ event RoyaltyManagerChanged(address indexed contractAddress, address indexed newRoyaltyManager); /** * @notice Emitted when mints are frozen permanently * @param contractAddress Initial contract that emitted event */ event MintsFrozen(address indexed contractAddress); /** * @notice Emitted when contract metadata is set * @param contractAddress Initial contract that emitted event * @param name New name * @param symbol New symbol * @param contractURI New contract uri */ event ContractMetadataSet(address indexed contractAddress, string name, string symbol, string contractURI); /************************** ERC721General events **************************/ /** * @notice Emitted when hashed metadata config is set * @param contractAddress Initial contract that emitted event * @param hashedURIData Hashed uri data * @param hashedRotationData Hashed rotation key * @param _supply Supply of tokens to mint w/ reveal */ event HashedMetadataConfigSet( address indexed contractAddress, bytes hashedURIData, bytes hashedRotationData, uint256 indexed _supply ); /** * @notice Emitted when metadata is revealed * @param contractAddress Initial contract that emitted event * @param key Key used to decode hashed data * @param newRotationKey Actual rotation key to be used */ event Revealed(address indexed contractAddress, bytes key, uint256 newRotationKey); /************************** ERC721GeneralBase events **************************/ /** * @notice Emitted when uris are set for tokens * @param contractAddress Initial contract that emitted event * @param ids IDs of tokens to set uris for * @param uris Uris to set on tokens */ event TokenURIsSet(address indexed contractAddress, uint256[] ids, string[] uris); /** * @notice Emitted when limit supply is set * @param contractAddress Initial contract that emitted event * @param newLimitSupply Limit supply to set */ event LimitSupplySet(address indexed contractAddress, uint256 indexed newLimitSupply); /************************** ERC721StorageUri events **************************/ /** * @notice Emits when a series collection has its base uri set * @param contractAddress Contract with updated base uri * @param newBaseUri New base uri */ event BaseUriSet(address indexed contractAddress, string newBaseUri); /************************** ERC721Editions / ERC721SingleEdition events **************************/ // Not adding EditionCreated, EditionMintedToOneRecipient, EditionMintedToRecipients // EditionCreated - handled by MetadataInitialized // EditionMintedToOneRecipient / EditionMintedToRecipients - handled via mint module events /************************** Deployment events **************************/ /** * @notice Emitted when Generative Series contract is deployed * @param deployer Contract deployer * @param contractAddress Address of contract that was deployed */ event GenerativeSeriesDeployed(address indexed deployer, address indexed contractAddress); /** * @notice Emitted when Series contract is deployed * @param deployer Contract deployer * @param contractAddress Address of contract that was deployed */ event SeriesDeployed(address indexed deployer, address indexed contractAddress); /** * @notice Emitted when MultipleEditions contract is deployed * @param deployer Contract deployer * @param contractAddress Address of contract that was deployed */ event MultipleEditionsDeployed(address indexed deployer, address indexed contractAddress); /** * @notice Emitted when SingleEdition contract is deployed * @param deployer Contract deployer * @param contractAddress Address of contract that was deployed */ event SingleEditionDeployed(address indexed deployer, address indexed contractAddress); /************************** ERC721 events **************************/ /** * @notice Emitted when `tokenId` token is transferred from `from` to `to` on contractAddress * @param contractAddress NFT contract token resides on * @param from Token sender * @param to Token receiver * @param tokenId Token being sent */ event Transfer(address indexed contractAddress, address indexed from, address to, uint256 indexed tokenId); /** * @notice Emit MinterRegistrationChanged */ function emitMinterRegistrationChanged(address minter, bool registered) external; /** * @notice Emit GranularTokenManagersSet */ function emitGranularTokenManagersSet(uint256[] calldata _ids, address[] calldata _tokenManagers) external; /** * @notice Emit GranularTokenManagersRemoved */ function emitGranularTokenManagersRemoved(uint256[] calldata _ids) external; /** * @notice Emit DefaultTokenManagerChanged */ function emitDefaultTokenManagerChanged(address newDefaultTokenManager) external; /** * @notice Emit DefaultRoyaltySet */ function emitDefaultRoyaltySet(address recipientAddress, uint16 royaltyPercentageBPS) external; /** * @notice Emit GranularRoyaltiesSet */ function emitGranularRoyaltiesSet( uint256[] calldata ids, IRoyaltyManager.Royalty[] calldata _newRoyalties ) external; /** * @notice Emit RoyaltyManagerChanged */ function emitRoyaltyManagerChanged(address newRoyaltyManager) external; /** * @notice Emit MintsFrozen */ function emitMintsFrozen() external; /** * @notice Emit ContractMetadataSet */ function emitContractMetadataSet( string calldata name, string calldata symbol, string calldata contractURI ) external; /** * @notice Emit HashedMetadataConfigSet */ function emitHashedMetadataConfigSet( bytes calldata hashedURIData, bytes calldata hashedRotationData, uint256 _supply ) external; /** * @notice Emit Revealed */ function emitRevealed(bytes calldata key, uint256 newRotationKey) external; /** * @notice Emit TokenURIsSet */ function emitTokenURIsSet(uint256[] calldata ids, string[] calldata uris) external; /** * @notice Emit LimitSupplySet */ function emitLimitSupplySet(uint256 newLimitSupply) external; /** * @notice Emit BaseUriSet */ function emitBaseUriSet(string calldata newBaseUri) external; /** * @notice Emit GenerativeSeriesDeployed */ function emitGenerativeSeriesDeployed(address contractAddress) external; /** * @notice Emit SeriesDeployed */ function emitSeriesDeployed(address contractAddress) external; /** * @notice Emit MultipleEditionsDeployed */ function emitMultipleEditionsDeployed(address contractAddress) external; /** * @notice Emit SingleEditionDeployed */ function emitSingleEditionDeployed(address contractAddress) external; /** * @notice Emit Transfer */ function emitTransfer(address from, address to, uint256 tokenId) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity 0.8.10; /** * @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}. */ /* solhint-disable */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/IERC1967.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967Upgrade is IERC1967 { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @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 v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // 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. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 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 + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
{ "optimizer": { "enabled": true, "mode": "z" }, "outputSelection": { "*": { "*": [ "abi" ] } }, "detectMissingLibraries": false, "forceEVMLA": false, "enableEraVMExtensions": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"EditionDoesNotExist","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidBurn","type":"error"},{"inputs":[],"name":"InvalidEditionSizeUpdate","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"InvalidManager","type":"error"},{"inputs":[],"name":"InvalidOperator","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"InvalidSize","type":"error"},{"inputs":[],"name":"ManagerDoesNotExist","type":"error"},{"inputs":[],"name":"ManagerRemoveBlocked","type":"error"},{"inputs":[],"name":"ManagerSwapBlocked","type":"error"},{"inputs":[],"name":"MetadataUpdateBlocked","type":"error"},{"inputs":[],"name":"MintFrozen","type":"error"},{"inputs":[],"name":"MinterRegistrationInvalid","type":"error"},{"inputs":[],"name":"NotMinter","type":"error"},{"inputs":[],"name":"NotTokenOwnerOrApproved","type":"error"},{"inputs":[],"name":"ReceiverNonImplementer","type":"error"},{"inputs":[],"name":"ReceiverRejectedTokens","type":"error"},{"inputs":[],"name":"RoyaltyBPSInvalid","type":"error"},{"inputs":[],"name":"RoyaltySetBlocked","type":"error"},{"inputs":[],"name":"SoldOut","type":"error"},{"inputs":[],"name":"TokenDoesNotExist","type":"error"},{"inputs":[],"name":"TransferFromZeroAddress","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipientAddress","type":"address"},{"indexed":true,"internalType":"uint16","name":"royaltyPercentageBPS","type":"uint16"}],"name":"DefaultRoyaltySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newDefaultTokenManager","type":"address"}],"name":"DefaultTokenManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"editionId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"size","type":"uint256"},{"indexed":true,"internalType":"address","name":"editionTokenManager","type":"address"}],"name":"EditionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"components":[{"internalType":"address","name":"recipientAddress","type":"address"},{"internalType":"uint16","name":"royaltyPercentageBPS","type":"uint16"}],"indexed":false,"internalType":"struct IRoyaltyManager.Royalty[]","name":"_newRoyalties","type":"tuple[]"}],"name":"GranularRoyaltiesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"GranularTokenManagersRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"indexed":false,"internalType":"address[]","name":"_tokenManagers","type":"address[]"}],"name":"GranularTokenManagersSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"editionId","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"oldSize","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"newSize","type":"uint128"}],"name":"HighlightUpdated1155EditionSize","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"bool","name":"registered","type":"bool"}],"name":"MinterRegistrationChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"MintsFrozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newRoyaltyManager","type":"address"}],"name":"RoyaltyManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_editionUri","type":"string"},{"internalType":"uint256","name":"_editionSize","type":"uint256"},{"internalType":"address","name":"_editionTokenManager","type":"address"},{"components":[{"internalType":"address","name":"recipientAddress","type":"address"},{"internalType":"uint16","name":"royaltyPercentageBPS","type":"uint16"}],"internalType":"struct IRoyaltyManager.Royalty","name":"editionRoyalty","type":"tuple"},{"internalType":"bytes","name":"mintVectorData","type":"bytes"}],"name":"createEdition","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_editionUri","type":"string"},{"internalType":"uint256","name":"_editionSize","type":"uint256"},{"internalType":"address","name":"_editionTokenManager","type":"address"},{"components":[{"internalType":"address","name":"recipientAddress","type":"address"},{"internalType":"uint16","name":"royaltyPercentageBPS","type":"uint16"}],"internalType":"struct IRoyaltyManager.Royalty","name":"editionRoyalty","type":"tuple"},{"internalType":"bytes","name":"mechanicVectorData","type":"bytes"}],"name":"createEditionWithMechanicVector","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_editionUri","type":"string"},{"internalType":"uint256","name":"_editionSize","type":"uint256"},{"internalType":"address","name":"_editionTokenManager","type":"address"},{"components":[{"internalType":"address","name":"recipientAddress","type":"address"},{"internalType":"uint16","name":"royaltyPercentageBPS","type":"uint16"}],"internalType":"struct IRoyaltyManager.Royalty","name":"editionRoyalty","type":"tuple"},{"internalType":"bytes","name":"mintVectorData","type":"bytes"},{"internalType":"bytes","name":"mechanicVectorData","type":"bytes"}],"name":"createEditionWithMechanicVectorAndPublicFixedPriceVector","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"editionSupply","outputs":[{"internalType":"uint128","name":"currentSupply","type":"uint128"},{"internalType":"uint128","name":"maxSupply","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"}],"name":"editionURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freezeMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"}],"name":"getEditionDetails","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"initialTokenId","type":"uint256"}],"internalType":"struct IEditionCollection.EditionDetails","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getEditionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"editionIds","type":"uint256[]"}],"name":"getEditionsDetailsAndUri","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"size","type":"uint256"},{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"initialTokenId","type":"uint256"}],"internalType":"struct IEditionCollection.EditionDetails[]","name":"","type":"tuple[]"},{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"highlightContractStandardHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintAmountToRecipient","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintAmountToRecipients","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"mintOneToRecipient","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"mintOneToRecipients","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minters","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"observability","outputs":[{"internalType":"contract IObservabilityV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"registerMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeDefaultTokenManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"removeGranularTokenManagers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeRoyaltyManager","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":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newName","type":"string"},{"internalType":"string","name":"newSymbol","type":"string"},{"internalType":"string","name":"newContractUri","type":"string"}],"name":"setContractMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"recipientAddress","type":"address"},{"internalType":"uint16","name":"royaltyPercentageBPS","type":"uint16"}],"internalType":"struct IRoyaltyManager.Royalty","name":"_royalty","type":"tuple"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_defaultTokenManager","type":"address"}],"name":"setDefaultTokenManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"uint128","name":"newSize","type":"uint128"}],"name":"setEditionSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"editionId","type":"uint256"},{"internalType":"string","name":"_uri","type":"string"}],"name":"setEditionURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"components":[{"internalType":"address","name":"recipientAddress","type":"address"},{"internalType":"uint16","name":"royaltyPercentageBPS","type":"uint16"}],"internalType":"struct IRoyaltyManager.Royalty[]","name":"_newRoyalties","type":"tuple[]"}],"name":"setGranularRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"address[]","name":"_tokenManagers","type":"address[]"}],"name":"setGranularTokenManagers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_royaltyManager","type":"address"}],"name":"setRoyaltyManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenManager","outputs":[{"internalType":"address","name":"manager","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenManagerByTokenId","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"unregisterMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
9c4d535b0000000000000000000000000000000000000000000000000000000000000000010009e91e035492a7f8d2819840055650a3c067d31899307fdd55f71002583600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x0004000000000002003000000000000200000060031002700000091d0b3001970003000000b1035500020000000103550000091d0030019d00000001002001900000000004000416000000a0020000390000000003000410000000980000c13d0000008002000039000000400020043f0000000400b0008c00000cf20000413d000000000301043b000000e0063002700000091f0060009c000003d10000613d000009200060009c0000000403100370000000c50000613d000009210060009c000000cf0c000039000003e10000613d000009220060009c00000024021003700000006508000039000000330d0000390000042c0000613d000009230060009c000001000e00008a000000d60000613d000009240060009c000000ae0000613d000009250060009c000008970000613d000009260060009c000000b50000613d000009270060009c000000e80000613d000009280060009c00000044051003700000013809000039000000ec0000613d000009290060009c0000012f0000613d0000092a0060009c000001340a000039000008bd0000613d0000092b0060009c000004790000613d0000092c0060009c0000014e0000613d0000092d0060009c000000bd0000613d0000092e0060009c000004b40000613d0000092f0060009c000000a40000613d000009300060009c000001590000613d000009310060009c000004bd0000613d000009320060009c000005150000613d000009330060009c000001a90000613d000009340060009c000002020000613d000009350060009c000002280000613d000009360060009c0000023a0000613d000009370060009c000000a40000613d000009380060009c000005180000613d000009390060009c0000057a0000613d0000093a0060009c000005e80000613d0000093b0060009c000006020000613d0000093c0060009c000006070000613d0000093d0060009c000002460000613d0000093e0060009c0000061c0000613d0000093f0060009c0000024a0000613d000009400060009c000002950000613d000009410060009c0000010407000039000006380000613d000009420060009c000006550000613d000009430060009c000006660000613d000009440060009c000006a70000613d000009450060009c000007070000613d000009460060009c000007200000613d000009470060009c000007760000613d000009480060009c000000ae0000613d000009490060009c000002a80000613d0000094a0060009c000002ac0000613d0000094b0060009c000007880000613d0000094c0060009c0000031f0000613d0000094d0060009c0000032f0000613d0000094e0060009c0000079c0000613d0000094f0060009c000003420000613d000009500060009c000007a50000613d000009510060009c000008420000613d000009520060009c000008530000613d000009530060009c000008810000613d000009540060009c000003460000613d000009550060009c0000036b0000613d000009560060009c000003bf0000613d000009570060009c00000cf20000c13d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b0000095a0010009c00000cf20000213d000000000202043b24701c230000040f000000aa0000013d000000400020043f000000000004004b00000cf20000c13d000000800030043f0000014000000443000001600030044300000020010000390000010000100443000000010100003900000120001004430000091e01000041000024710001042e0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b247019280000040f000000400300043d0000000000130435000000200200003900000b4e0000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b24701ae00000040f000004ba0000013d000000000004004b00000cf20000c13d0000013701000039000000000101041a000000000001004b00000a710000613d000000010110008a000007a10000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b0000095a0010009c00000cf20000213d247018600000040f0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b000009770010019800000cf20000c13d0000097801100197000009ce0010009c00000000020000390000000102006039000009cf0010009c00000001022061bf000009640010009c00000001022061bf000000800020043f000007a20000013d000000000004004b00000cf20000c13d0000013502000039000100db0000003d000023d30000013d000000000054004b0000032b0000c13d000000800010043f000000000004004b0000094d0000613d000000000020043f000009c6030000410000000002000019000000000012004b0000095a0000813d000100e70000003d000023980000013d000000e30000013d000000000004004b00000cf20000c13d000000cb010000390000079f0000013d0000006400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000202043b001500000002001d0000095a0020009c00000cf20000213d000000000205043b001300000002001d000000000203043b001400000002001d000000000208041a0000095a032001970000000002000411000000000032004b000001010000c13d0000001402b0008a000000000121034f000000000101043b00000060021002700000095a01200197000101040000003d0000227c0000013d0000071e0000613d247018d60000040f000000cf01000039000000000101041a0000099401100197000009950010009c00000acb0000613d0001010d0000003d0000239e0000013d00000ce80000a13d000101100000003d000022da0000013d000009660020009c0000155a0000213d000101140000003d000023070000013d0000095b043001970000000000420435000000010200008a000000130220014f000000000024004b00000a710000213d001200130040002d000009960030009c0000011f0000413d000000120010006b00000ce60000213d000000400400043d000009690040009c0000155a0000213d0000002001400039000000400010043f000000000004043500000015010000290000001402000029000000130300002924701f6b0000040f00000014010000290001012c0000003d000022d20000013d0000096c022001970000001204000029000010e10000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000102043b001500000001001d000000000103043b000000000010043f000000ce010000390001013a0000003d0000228b0000013d000000c003000039000000400030043f000000000201041a0000095a01200198000000800010043f000000a0022002700000ffff0420018f000000a00040043f000009330000c13d0000010003000039000000400030043f0000012002000039000000cd01000039000000000401041a0000095a01400197000000c00010043f000000a0044002700000ffff0440018f000000e00040043f000009340000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b0000013702000039000000000202041a000000000012004b000007a10000213d000009b90100004100000f180000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b001500000001001d0000095a0010009c00000cf20000213d0000000001000415001400000001001d247018280000040f0000001501000029247018930000040f000000000001004b0000061a0000613d000000400100043d0000091d0010009c001300000001001d0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d0200003900000003030000390000000106000039000009a70400004100000015050000292470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001200000001001d002b095a0010019b000101810000003d000022780000013d0000002b0440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000012010000290000095a021001970000001305000029000000240150003900000001030000390000000000310435000009a80100004100000000001504350000000401500039000000150300002900000000003104350000000001000414000000040020008c0000019d0000613d0000004404000039000000000305001900000013050000290000000006000019247016100000040f0000001305000029000000000001004b00000d620000613d0001019f0000003d0000245d0000013d000101a10000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c000004270000a13d00000cf20000013d000000000004004b00000cf20000c13d00000000010b0019247016e80000040f001100000001001d001200000002001d0000000001000415000f00000001001d000101b30000003d000023ff0000013d0000095a021001970000000001000411000000000021004b000001b90000c13d000101b90000003d0000224c0000013d0010095a0010019b0000000002000019000000120020006c00000b510000813d001400000002001d00000005012002100000001101100029001300000001001d0000000201100367000000000101043b001500000001001d000000000010043f000000cc01000039000101c80000003d000022850000013d0000095a02100198000007860000613d000000400500043d000000240150003900000015030000290000000000310435000009970100004100000000001504350000000401500039000000100300002900000000003104350000000001000414000000040020008c000001d80000c13d0000000102000031000001e10000013d00000000030500190000004404000039001500000005001d0000002006000039247016100000040f0000000102000031000000000001004b00000d1e0000613d00000015050000290000001f01200039000000200300008a000000000331016f0000000001530019000101e70000003d000023e70000013d000009620010009c0000155a0000213d00000001003001900000155a0000c13d000000400010043f000009630020009c00000cf20000213d000000200020008c00000cf20000413d0000000001050433000101f30000003d000022520000013d00000cf20000c13d000000000001004b000009be0000613d00000013010000290000000201100367000000000101043b000000000010043f000000cc01000039000101fd0000003d000023340000013d0000097a02200197000000000021041b00000014020000290000000102200039000001bb0000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b001500000001001d0000095a0010009c00000cf20000213d0000000001000415001400000001001d247018d60000040f0000001501000029247021ab0000040f000000000001004b000006640000613d0000001501000029247021d30000040f000000000001004b000006640000c13d000000400100043d0000002003100039000009640200004100000000002304350000002402100039000009ae04000041000000000042043500000024020000390000000000210435000009af0010009c0000155a0000213d0000006002100039000000400020043f0000001502000029000000040020008c00000de70000c13d0000000001030433000000000010043f00000deb0000013d000000000004004b00000cf20000c13d0000000001000412003000000001001d002f00000000003d000080050100003900000044030000390000000004000415000000300440008a0000000504400210000009aa02000041247022230000040f0000095a011001970000000002000410000000000012004b000009410000c13d000009ad01000041000007a10000013d000000000004004b00000cf20000c13d00000000010b0019247017720000040f0000006502000039000000000202041a000000000112013f0000095a0010019800000000020000390000000102006039000000400100043d000006360000013d000000000004004b00000cf20000c13d00000000010d041a000007a00000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000102043b000009620010009c00000cf20000213d000102530000003d000024080000013d0000006501000039000000000101041a0000095a021001970000000001000411000000000021004b0000025b0000c13d0001025b0000003d0000224c0000013d0000095a011001970001025e0000003d0000227c0000013d0000071e0000613d247018d60000040f000000cf01000039000000000101041a0000099401100197000009950010009c00000acb0000613d000102670000003d0000239e0000013d00000ce80000a13d00000013010000290000000001010433001200000001001d0001026d0000003d000022da0000013d000009660020009c0000155a0000213d000102710000003d000023070000013d0000095b043001970000000000420435000000010200008a000000120220014f000000000024004b00000a710000213d001000120040002d000009960030009c0000027c0000413d000000100010006b00000ce60000213d0000001301000029001100200010003d0000000002000019000000120020006c000010d60000813d00000013010000290000000001010433000000000021004b00000de30000a13d000000400300043d000009690030009c0000155a0000213d0000000501200210001500000002001d000000110110002900000000010104330000002002300039000000400020043f00000000000304350000095a01100197000000140200002924701dae0000040f000000150200002900000001022000390000027f0000013d000000000004004b00000cf20000c13d00000136020000390001029a0000003d000023d30000013d000000000553013f00000001005001900000032b0000c13d000000800010043f000000000004004b0000094d0000613d000000000020043f0000099f030000410000000002000019000000000012004b0000095a0000813d000102a70000003d000023980000013d000002a30000013d000000000004004b00000cf20000c13d0000098b01000041000007a10000013d000000000004004b00000cf20000c13d00000000010b0019247017b60000040f001200000001001d00000000030200190000000001000415001100000001001d000000000400041a0000ffff00400190001500000002001d000002c90000613d0000000001000410002000000001001d00008002010000390000002403000039001400000004001d0000000004000415000000200440008a00000005044002100000096002000041247022230000040f00000014040000290000001503000029000000ff0240018f000000010020008c00000a070000c13d000000000001004b00000a070000c13d0000ff0000400190000001000100008a000000000114016f00000001011001bf000000000010041b001400200030003d001300400030003d001000600030003d000f00800030003d000e00a00030003d000d00c00030003d000c00e00030003d000009c20000c13d0000ffff0200008a000000000121016f00000100011001bf000000000010041b0000000001000415000b00000001001d0000000001030433000009630010009c00000cf20000213d000000e00010008c00000cf20000413d00000014020000290000000004020433000009620040009c00000cf20000213d000102e70000003d000023db0000013d000009620010009c00000cf20000213d000102eb0000003d000024220000013d000009620010009c00000cf20000213d000102ef0000003d000023cb0000013d0000095a0010009c00000cf20000213d0000000e010000290000000001010433000009620010009c00000cf20000213d00000015021000290000003f012000390000000a04000029000000000041004b0000000003000019000009860300804100000986011001970000098604400197000000000541013f000000000041004b00000000010000190000098601004041000009860050009c000000000103c019000000000001004b00000cf20000c13d00000020012000390000000003010433000009620030009c0000155a0000213d00000005043002100000003f0540003900000987055001970001030e0000003d0000240f0000013d000009620050009c0000155a0000213d00000001006001900000155a0000c13d000103140000003d000023c30000013d00000cf20000213d00000014030000290000002001100039000000000021004b000013f20000813d00000000040104330000095a0040009c00000cf20000213d00000020033000390000000000430435000003160000013d000000000004004b00000cf20000c13d00000000020a041a000000010320019000000001012002700000007f0110618f0000001f0010008c00000000040000390000000104002039000000000442013f00000001004001900000094f0000613d000009a501000041000000000010043f00000022010000390000155d0000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b0000095a0010009c00000cf20000213d000000000202043b001500000002001d0000095a0020009c00000cf20000213d24701c1c0000040f000000150200002924701c200000040f000000000101041a000000ff001001900000000002000039000000010200c039000002440000013d000000000004004b00000cf20000c13d00000000010c041a000007a00000013d0000006400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b000c00000001001d0000095a0010009c00000cf20000213d000000000105043b000900000001001d000000000102043b000a00000001001d0000000001000415000700000001001d247018d60000040f0000000a01000029247019280000040f001500000001001d0000006501000039000000000101041a0000095a011001970000000002000411000000000012004b001300000002001d0000000001020019000003620000c13d000103620000003d0000224c0000013d000800000001001d0000000a01000029000103660000003d000022d20000013d0000095b03200197000000090030006c00000a180000813d000009720100004100000f180000013d000000000004004b00000cf20000c13d0001036f0000003d000022a20000013d0000095a001001980000037d0000613d000103730000003d000023460000013d0000095a02200197000000000301041a0000095c03300197000000000223019f00000012030000290000000003030433000000a0033002100000095d03300197000000000232019f000000000021041b000000150000006b000006300000613d0000000f010000290000001502100029247019eb0000040f001400000001001d001200000004001d000000400100043d001500000001001d0000095e0010009c0000155a0000213d0011095a0030019b0000001505000029000000c001500039000000400010043f0000006001500039000000010300003900000000003104350000095a012001970000004002500039000000000012043500000013010000290000095f011001970000002002500039000000000012043500000000010004100000095a011001970000000000150435000000a001500039000000000001043500000080015000390000000000010435001600110000002d000080020100003900000024030000390000000004000415000000160440008a00000005044002100000096002000041247022230000040f000000000001004b000009990000613d000000400200043d00000961010000410000000000120435000f00000002001d000000040120003900000015020000290000001403000029000000120400002924701a220000040f000000000301001900000000010004140000001102000029000000040020008c000003bb0000613d0000000f0500002900000000045300490000000003050019000103ba0000003d000022bb0000013d00000d620000613d000103bd0000003d000022b60000013d0000000f0200002900000be60000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b000000000010043f000000200090043f000000400200003900000000010000192470220f0000040f000000000101041a0000095b02100197000000800020043f0000008001100270000000a00010043f0000008001000039000000400200003900000b4f0000013d000000000004004b00000cf20000c13d000000c903000039000000000103041a000000800010043f000000000030043f00000958030000410000000004000019000000000014004b0000091c0000813d0000002002200039000000000503041a000000000052043500000001044000390000000103300039000003d90000013d000000000004004b00000cf20000c13d0000000001000415001400000001001d247018280000040f247018d60000040f000000cf02000039000000000102041a000009cb0110019700000995011001c7000000000012041b000000400100043d0000091d0010009c001500000001001d0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d020000390000000103000039000009cc040000412470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001300000001001d002e095a0010019b000104030000003d000022780000013d0000002e0440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000013010000290000095a02100197000009cd01000041000000150300002900000000001304350000000001000414000000040020008c000004180000613d000000040400003900000015050000290000000006000019247016100000040f0000001503000029000000000001004b00000d620000613d0000001f010000390000000101100031000000200200008a000000000221016f00000000013200190001041f0000003d000023fb0000013d000009620010009c0000155a0000213d00000001002001900000155a0000c13d000000400010043f00000097010000390000000102000039000000000021041b000000000100041500000014020000290000000001120049000000000100000200000b2d0000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000402043b000009620040009c00000cf20000213d00000023024000390000000000b2004b00000cf20000813d0000000402400039000000000121034f000000000201043b000000000103043b001500000001001d000000240140003900000000030b0019247016580000040f001400000001001d0000000001000415001200000001001d0000001501000029247019280000040f000000000501001900000000010004110000006502000039000000000202041a0000095a02200197000000000021004b0000044c0000c13d0001044c0000003d0000224c0000013d000000000005004b0000000003000410000000330200003900000a330000c13d000000000202041a000000000112013f0000095a0010019800000e2f0000c13d0000001501000029000000000010043f0000013901000039000104590000003d0000228b0000013d000000140200002924701a5e0000040f000000400100043d001300000001001d000009660010009c0000155a0000213d00000013030000290000004001300039000000400010043f00000020013000390000001502000029000000000021043500000001010000390000000000130435000000400100043d001500000001001d000009660010009c0000155a0000213d00000015020000290000004001200039000000400010043f0000000105000039000000000152043600000060020000390000000004000019000000010050019000000ddf0000613d0000000004140019000000000024043500000000050000190000002004000039000004720000013d000000a400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b001300000001001d0000095a0010009c00000cf20000213d000000000102043b000e00000001001d0000095a0010009c00000cf20000213d000000000105043b000009620010009c00000cf20000213d000000040110003900000000020b001900150000000b001d2470173b0000040f0000001502000029001000000001001d00000064010000390000000201100367000000000101043b000009620010009c00000cf20000213d00000004011000392470173b0000040f0000001503000029000f00000001001d00000002020003670000008401200370000000000101043b000009620010009c00000cf20000213d0000002304100039000000000034004b00000cf20000813d0000000404100039000000000242034f000000000202043b0000002401100039247016580000040f000a00000001001d0000006501000039000000000101041a0000095a011001970000000002000411000b00000002001d000000000012004b00000ebd0000c13d000000140100008a00000000011000310000000201100367000000000101043b0000006002100270000000130020006c00000ec00000c13d00000ec60000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b24701ad70000040f0000000002010019000000400100043d00000b4a0000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b000009620010009c00000cf20000213d000000040110003900000000020b001900150000000b001d2470177d0000040f0000001502000029001300000001001d00000024010000390000000201100367000000000101043b000009620010009c00000cf20000213d00000004011000392470173b0000040f00000013020000290000000002020433001200000001001d0000000031010434001100000003001d000000000012004b00000f170000c13d000009620020009c0000155a0000213d00000005012002100000003f031000390000098703300197000000400400043d0000000003340019001000000004001d000000000043004b00000000040000390000000104004039000009620030009c0000155a0000213d00000001004001900000155a0000c13d000000400030043f00000010030000290000000002230436000f00000002001d0000001f0210018f000000000001004b000004f60000613d0000000f04000029000000000114001900000000030000310000000203300367000000003503043c0000000004540436000000000014004b000004f20000c13d000000000002004b0000001301000029000e00200010003d000000000300001900000013010000290000000001010433000000000013004b00000f590000813d00000012010000290000000001010433000000000031004b00000de30000a13d00000005043002100000000e01400029001400000004001d0000001102400029000000000202043300000000010104330000095a01100197001500000003001d24701c230000040f000000150300002900000010020000290000000002020433000000000032004b00000de30000a13d00000014040000290000000f0240002900000000001204350000000103300039000004fa0000013d00000000010b0019247017b60000040f247018600000040f0000006400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000102043b000009620010009c00000cf20000213d000105210000003d000024080000013d00000002010003670000004402100370000000000202043b001200000002001d0000006502000039000000000202041a0000095a032001970000000002000411000000000032004b000005300000c13d000000140200008a0000000002200031000000000121034f000000000101043b00000060021002700000095a01200197000105330000003d0000227c0000013d0000071e0000613d247018d60000040f000000cf01000039000000000101041a0000099401100197000009950010009c00000acb0000613d0001053c0000003d0000239e0000013d00000ce80000a13d00000013010000290000000001010433001100000001001d000000000020043f0000013801000039000105440000003d0000228b0000013d000000400400043d000009660040009c0000155a0000213d0000004002400039000000400020043f000000000201041a0000002003400039000000800120027000000000001304350000095b0320019700000000003404350000001106000029000000000006004b000005560000613d000000010400008a00000000046400d9000000120040006c00000a710000413d00000012046000b9000000010500008a000000000554013f000000000053004b00000a710000213d000f00000043001d000009960020009c000005600000413d0000000f0010006b00000ce60000213d0000001301000029001000200010003d0000000002000019000000110020006c000010dc0000813d00000013010000290000000001010433000000000021004b00000de30000a13d000000400400043d000009690040009c0000155a0000213d0000000501200210001500000002001d000000100110002900000000010104330000002002400039000000400020043f00000000000404350000095a011001970000001402000029000000120300002924701f6b0000040f00000015020000290000000102200039000005630000013d000000e400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000303043b000009620030009c00000cf20000213d00000023023000390000000000b2004b00000cf20000813d0000000402300039000000000121034f000000000201043b000000240130003900000000030b001900150000000b001d247016580000040f0000001503000029001400000001001d00000002010003670000002402100370000000000202043b001300000002001d0000004401100370000000000101043b001200000001001d0000095a0010009c00000cf20000213d0000000001030019247017d20000040f0000001504000029001100000001001d0000000201000367000000a402100370000000000202043b000009620020009c00000cf20000213d0000002303200039000000000043004b00000cf20000813d0000000403200039000000000331034f000000000303043b001000000003001d000009620030009c00000cf20000213d0000002403200039000f00000003001d000e00100030002d0000000e0040006b00000cf20000213d000000c402100370000000000202043b000009620020009c00000cf20000213d0000002303200039000000000043004b00000cf20000813d0000000403200039000000000131034f000000000101043b000d00000001001d000009620010009c00000cf20000213d0000002402200039000c00000002001d000b000d0020002d0000000b0040006b00000cf20000213d0000000001000415000a00000001001d247018280000040f247018d60000040f00000014010000290000001302000029000000120300002924701afd0000040f001500000001001d000000110100002900000000010104330000095a00100198000005dd0000613d0000001501000029000000000010043f000000ce01000039000105d10000003d0000228b0000013d000000110400002900000000020404330000095a02200197000000000301041a0000095c03300197000000000223019f00000020034000390000000003030433000000a0033002100000095d03300197000000000232019f000000000021041b000000100000006b000010ea0000c13d0000000d0000006b000012200000c13d000105e30000003d000023020000013d0000000a011000690000000001000002000000400100043d0000001502000029000006360000013d000000000004004b00000cf20000c13d247018280000040f0000003303000039000000000103041a0000097a02100197000000000023041b000000400200043d0000091d0020009c0000091d02008041000000400220021000000000030004140000091d0030009c0000091d03008041000000c003300210000000000223019f0000095a051001970000097b012001c70000800d020000390000000303000039000009a90400004100000000060000192470223c0000040f000000010020019000000b2d0000c13d00000cf20000013d000000000004004b00000cf20000c13d0000013701000039000000000101041a000007a10000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b001500000001001d0000095a0010009c00000cf20000213d0000000001000415001400000001001d247018280000040f0000001501000029000000000010043f000000ca01000039000106170000003d0000228b0000013d000000000301041a000000000003004b00000a6d0000c13d000009b80100004100000f180000013d000000000004004b00000cf20000c13d000106200000003d000022a20000013d0000095a001001980000062e0000613d000106240000003d000023460000013d0000095a02200197000000000301041a0000095c03300197000000000223019f00000012030000290000000003030433000000a0033002100000095d03300197000000000232019f000000000021041b000000150000006b000009620000c13d000106320000003d000023020000013d00000010011000690000000001000002000000400100043d00000013020000290000000000210435000007a30000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000403043b0000095a0040009c00000cf20000213d0000000003040019000000000402043b000000000004004b0000000002000039000000010200c039001500000004001d000000000024004b00000cf20000c13d000000000208041a0000095a022001970000000004000411000000000024004b000006500000c13d0000001402b0008a000000000121034f000000000101043b00000060041002700000095a01400197000000000031004b00000bb50000c13d0000099e0100004100000f180000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b001500000001001d0000095a0010009c00000cf20000213d0000000001000415001400000001001d247018d60000040f0000001501000029247021780000040f000000000001004b00000a750000c13d000009b20100004100000f180000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000102043b001500000001001d0000095b0010009c00000cf20000213d000000000103043b001400000001001d247018280000040f00000014020000290000013701000039000000000101041a000000000021004b00000ce80000a13d000106780000003d000022da0000013d000009660020009c0000155a0000213d0001067c0000003d000023070000013d0000095b0430019700000000004204350000001505000029000000000005004b00000d280000613d000009960030009c00000d280000413d000000000045004b00000d280000413d000000400200043d0000002003200039000000000053043500000000001204350000091d0020009c0000091d02008041000000400120021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f00000967011001c70000800d0200003900000002030000390000099a0400004100000014050000292470223c0000040f000000010020019000000cf20000613d0000001401000029000000000010043f0000013801000039000000200010043f000000400200003900000000010000192470220f0000040f00000015020000290000008002200210000000000301041a0000095b03300197000000000223019f000000000021041b00000b2d0000013d000000000004004b00000cf20000c13d0000000001000415001500000001001d000106ad0000003d000023ff0000013d0000095a021001970000000001000411000000000021004b000006b30000c13d000106b30000003d0000224c0000013d000000cb02000039000000000202041a0000095a02200198000007860000613d000000400500043d000009970300004100000000003504350000095a0110019700000004035000390000000000130435000000240150003900000000000104350000000001000414000000040020008c000006cb0000613d000000440400003900000020060000390000000003050019001400000005001d0000001405000029247016100000040f0000001405000029000000000001004b00000d620000613d000106cd0000003d000023600000013d000009620030009c0000155a0000213d00000001002001900000155a0000c13d0000001402000029000000400020043f000009630010009c00000cf20000213d000000200010008c00000cf20000413d0000000001050433000106da0000003d000022520000013d00000cf20000c13d000000000001004b000009be0000613d000000cb02000039000000000102041a0000097a01100197000000000012041b00000014010000290000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d020000390000000203000039000009980400004100000000050000192470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001300000001001d0023095a0010019b000106f80000003d000022780000013d000000230440008a00000005044002100000096002000041247022230000040f000000000001004b000009990000613d00000013010000290000095a0210019700000999010000410000001403000029000000000013043500000004013000390000000000010435000000000100041400000e800000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000202043b001500000002001d0000095a0020009c00000cf20000213d000000000203043b001400000002001d000000000208041a0000095a032001970000000002000411000000000032004b0000071a0000c13d0000001402b0008a000000000121034f000000000101043b00000060021002700000095a012001970001071d0000003d0000227c0000013d00000ac50000c13d000009c50100004100000f180000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000303043b000009620030009c00000cf20000213d00000023043000390000000000b4004b00000cf20000813d0000000404300039000000000441034f000000000404043b001300000004001d000009620040009c00000cf20000213d001200240030003d0000001303000029000000050330021000000012033000290000000000b3004b00000cf20000213d000000000202043b000009620020009c00000cf20000213d00000023032000390000000000b3004b00000cf20000813d0000000403200039000000000131034f000000000101043b001100000001001d000009620010009c00000cf20000213d001000240020003d0000001101000029000000060110021000000010011000290000000000b1004b00000cf20000213d0000000001000415000b00000001001d0001074c0000003d000023ff0000013d0000095a021001970000000001000411000000000021004b000007520000c13d000107520000003d0000224c0000013d000000cf02000039000000000202041a000f095a0020019c00000fa80000c13d0000003302000039000000000202041a000000000112013f0000095a0010019800000e2f0000c13d0000000003000019000000130030006c0000118c0000813d000000110030006c00000de30000813d0000000601300210000000100410002900000020024000390000000201000367000000000221034f000000000202043b0000ffff0020008c00000cf20000213d001500000004001d000027100020008c000008510000213d0000000502300210001400000003001d0000001202200029000000000121034f000107710000003d000023bb0000013d0000001502000029247018eb0000040f000000140300002900000001033000390000075c0000013d000000000004004b00000cf20000c13d0000000001000415001500000001001d0001077c0000003d000023ff0000013d0000095a021001970000000001000411000000000021004b000007820000c13d000107820000003d0000224c0000013d000000cf02000039000000000202041a0000095a022001980000099a0000c13d000009b70100004100000f180000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b001500000001001d24701ac40000040f0000013701000039000000000101041a0000001502000029000000000021004b00000ce80000a13d000000000102001924701bf70000040f0000002002000039000000400300043d001500000003001d0000000002230436247017010000040f00000b4c0000013d000000000004004b00000cf20000c13d000000d001000039000000000101041a0000095a01100197000000800010043f0000008001000039000000200200003900000b4f0000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000303043b000009620030009c00000cf20000213d00000023043000390000000000b4004b00000cf20000813d0000000404300039000000000441034f000000000404043b001000000004001d000009620040009c00000cf20000213d000f00240030003d000000100300002900000005033002100000000f033000290000000000b3004b00000cf20000213d000000000202043b000009620020009c00000cf20000213d00000023032000390000000000b3004b00000cf20000813d0000000403200039000000000131034f000000000101043b000e00000001001d000009620010009c00000cf20000213d000d00240020003d0000000e0100002900000005011002100000000d011000290000000000b1004b00000cf20000213d0000000001000415000a00000001001d000107d10000003d000023ff0000013d0000095a021001970000000001000411000000000021004b000007d70000c13d000107d70000003d0000224c0000013d0000003302000039000000000202041a000000000212013f000c095a0010019b000b095a0020019b0000000002000019000000100020006c000011400000813d0000000e0020006c00000de30000813d001400000002001d0000000502200210001500000002001d0000000d01200029001300000001001d0000000201100367000000000101043b0000095a0010009c00000cf20000213d247021780000040f000000000001004b000006640000613d00000015020000290000000f01200029001500000001001d0000000201100367000000000101043b247019280000040f000000000001004b0000082d0000613d001200000001001d00000015010000290000000201100367000000000101043b001100000001001d0000001401000029000000000010043f000000cc01000039000107ff0000003d000022850000013d000000400500043d0000002402500039000000110300002900000000003204350000095a01100197000000440250003900000000001204350000098001000041000000000015043500000004015000390000000c02000029000000000021043500000012020000290000000001000414000000040020008c000008180000613d00000000030500190000006404000039001200000005001d00000012050000290000002006000039247016100000040f0000001205000029000000000001004b00000d620000613d0001081a0000003d0000245d0000013d0001081c0000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c000000150300002900000cf20000213d000000200010008c00000cf20000413d0000000001050433000108290000003d000022520000013d00000cf20000c13d000000000001004b000008300000c13d00000cd50000013d0000000b0000006b000000150300002900000e2f0000c13d00000002010003670000001302100360000000000202043b001300000002001d0000095a0020009c00000cf20000213d000000000131034f000000000101043b000000000010043f000000cc010000390001083c0000003d000023340000013d0000097a0220019700000013022001af000000000021041b00000014020000290000000102200039000007dd0000013d0000004400b0008c00000cf20000413d000000000004004b00000cf20000c13d0000000001000415001500000001001d247018d60000040f000000650400003900000002010003670000002402100370000000000302043b0000ffff0030008c00000cf20000213d000027100030008c00000acd0000a13d000009930100004100000f180000013d000000a400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000303043b001500000003001d0000095a0030009c00000cf20000213d000000000202043b001400000002001d0000095a0020009c00000cf20000213d0000008402100370000000000302043b000009620030009c00000cf20000213d00000023023000390000000000b2004b00000cf20000813d0000000402300039000000000221034f000000000202043b0000006401100370000000000101043b001200000001001d000000000105043b001300000001001d000000240130003900000000030b0019247016580000040f0000006503000039001100000001001d000000000103041a0000095a011001970000000004000411000000000014004b00000d2a0000c13d000000140100008a00000000011000310000000201100367000000000101043b00000060021002700000001501000029000000000012004b00000d2f0000c13d00000d340000013d0000002400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000103043b001500000001001d0000095a0010009c00000cf20000213d247018280000040f0000001501000029000000000001004b00000b2c0000c13d000000400100043d0000006402100039000009730300004100000000003204350000004402100039000009740300004100000000003204350000002402100039000000260300003900000a100000013d000000000004004b00000cf20000c13d00000000010b0019247016e80000040f000e00000001001d000f00000002001d000009620020009c0000155a0000213d0000000f010000290000000501100210001300000001001d0000003f01100039001009870010019b000000400200043d0000001001200029001100000002001d000108a90000003d000023fb0000013d000009620010009c0000155a0000213d00000001002001900000155a0000c13d000000400010043f00000011010000290000000f020000290000000001210436001200000001001d0000000002000019000000130020006c00000b300000813d001400120020002d001500000002001d24701ac40000040f0000001502000029000000140300002900000000001304350000002002200039000008b30000013d0000006400b0008c00000cf20000413d000000000004004b00000cf20000c13d000000000303043b000009620030009c00000cf20000213d00000023043000390000000000b4004b00000cf20000813d0000000404300039000000000441034f000000000404043b001500000004001d000009620040009c00000cf20000213d0000002404300039001400000004001d00000015034000290000000000b3004b00000cf20000213d000000000202043b000009620020009c00000cf20000213d00000023032000390000000000b3004b00000cf20000813d0000000403200039000000000331034f000000000303043b001300000003001d000009620030009c00000cf20000213d0000002403200039001200000003001d00000013023000290000000000b2004b00000cf20000213d000000000205043b000009620020009c00000cf20000213d00000023032000390000000000b3004b00000cf20000813d0000000403200039000000000131034f000000000101043b001100000001001d000009620010009c00000cf20000213d0000002402200039001000000002001d00000011012000290000000000b1004b00000cf20000213d0000000001000415000e00000001001d247018280000040f000000000300003100000014010000290000001502000029247016580000040f000f00000001001d000000000300003100000012010000290000001302000029247016580000040f00000000020100190000000f0100002924701b5f0000040f000109050000003d000022bf0000013d0000032b0000c13d000000110200002924701a4c0000040f00000011010000290000001f0010008c000012b20000a13d0000013401000039000000000010043f000000200100008a000000110310017f0000098101000041000000020200036700000000040000190000001006000029000000000034004b0000000005640019000012bc0000813d000000000552034f000000000505043b000000000051041b00000020044000390000000101100039000009130000013d000000410120008a000000200200008a000000000321016f000009590030009c0000155a0000213d0000008001300039000000400010043f00000020020000390000000000210435000000a004300039000000800200043d00000000002404350000008004000039000000c0033000390000000005000019000000000025004b000009c00000813d000000200440003900000000060404330000095a06600197000000000363043600000001055000390000092b0000013d000000e0020000390000001506000029000000000006004b0000093b0000613d000000010500008a00000000056500d9000000000045004b00000a710000413d000000000013043500000000016400a9000027100110011a0000000000120435000000400200003900000b4e0000013d0000097501000041000000800010043f0000002001000039000000840010043f0000003801000039000000a40010043f000009ab01000041000000c40010043f000009ac01000041000000e40010043f000000800100003900000a160000013d0000000001e3016f00000b460000013d000000800010043f000000000003004b00000b450000613d0000000000a0043f00000981030000410000000002000019000000000012004b0000095a0000813d000109590000003d000023980000013d000009550000013d000009820120009a000009830010009c0000155a0000413d0000003f01200039000000200200008a000000000121016f000000800110003900000b480000013d0000000f0100002900000015021000292470196f0000040f000000400a00043d00150000000a001d000009a000a0009c0000155a0000213d0014095a0010019b000000150c000029000001c001c00039000000400010043f0000016001c00039000000010a0000390000000000a104350000001301000029000009a101100197000001400ac0003900000000001a04350000095a012001970000006002c000390000000000120435000009a1013001970000002002c000390000000000120435000009a1014001970000004002c000390000000000120435000009a2015001970000012002c000390000000000120435000009a101600197000000e002c000390000000000120435000009a1017001970000008002c000390000000000120435000009a1018001970000010002c0003900000000001204350000095a01900197000000c002c00039000000000012043500000000010004100000095a01100197000109900000003d000023a30000013d002500140000002d000109930000003d000022780000013d000000250440008a00000005044002100000096002000041247022230000040f000000000001004b00000bd10000c13d000023900000013d000000400500043d0000098c0300004100000000003504350000095a01100197000000040350003900000000001304350000000001000414000000040020008c000009ac0000613d000000240400003900000020060000390000000003050019001400000005001d0000001405000029247016340000040f0000001405000029000000000001004b00000d620000613d000109ae0000003d000023600000013d000009620030009c0000155a0000213d00000001002001900000155a0000c13d0000001402000029000000400020043f000009630010009c00000cf20000213d000000200010008c00000cf20000413d0000000001050433000109bb0000003d000022520000013d00000cf20000c13d000000000001004b00000e570000c13d000009b60100004100000f180000013d000000000213004900000b4f0000013d0000000001000415000b00000001001d0000000001030433000009630010009c00000cf20000213d000000e00010008c00000cf20000413d00000014020000290000000004020433000009620040009c00000cf20000213d000109cf0000003d000023db0000013d000009620010009c00000cf20000213d000109d30000003d000024220000013d000009620010009c00000cf20000213d000109d70000003d000023cb0000013d0000095a0010009c00000cf20000213d0000000e010000290000000001010433000009620010009c00000cf20000213d00000015021000290000003f012000390000000a04000029000000000041004b0000000003000019000009860300804100000986011001970000098604400197000000000541013f000000000041004b00000000010000190000098601004041000009860050009c000000000103c019000000000001004b00000cf20000c13d00000020012000390000000003010433000009620030009c0000155a0000213d00000005043002100000003f054000390000098705500197000109f60000003d0000240f0000013d000009620050009c0000155a0000213d00000001006001900000155a0000c13d000109fc0000003d000023c30000013d00000cf20000213d00000014030000290000002001100039000000000021004b0000142f0000813d00000000040104330000095a0040009c00000cf20000213d00000020033000390000000000430435000009fe0000013d000000400100043d00000064021000390000098403000041000000000032043500000044021000390000098503000041000000000032043500000024021000390000002e030000390000000000320435000009750200004100000000002104350000000402100039000000200300003900000000003204350000008402000039247021fd0000040f000600000003001d000500000002001d0000001504000029000000000004004b00000bf10000c13d0000000c01000029000000000010043f000001040100003900010a220000003d0000228b0000013d00000008020000290000095a02200197000000000020043f00010a270000003d000022850000013d000000ff00100190000000650200003900000a2e0000c13d00000008030000290000000c0130014f0000095a0010019800000e2f0000c13d00000000030004150000000c0000006b00000d750000c13d000009700100004100000f180000013d000000400600043d001300000006001d0000006402600039000000a00400003900000000004204350000004402600039000000150400002900000000004204350000095a0110019700000024026000390000000000120435000009c70100004100000000001604350000095a0130019700000004026000390000000000120435000000a4026000390000001401000029001100000005001d247016ce0000040f0000001102000029000000130500002900000084045000390000000603000039000000000034043500000000030100190000000001000414000000040020008c00000a580000613d0000000004530049000000200600003900000000030500190000001305000029247016100000040f0000001305000029000000000001004b00000d620000613d00010a5a0000003d0000245d0000013d00010a5c0000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d000000200010008c00000cf20000413d000000000105043300010a680000003d000022520000013d00000cf20000c13d000000000001004b000004540000c13d000009c80100004100000f180000013d000000c904000039000000000204041a000000000002004b00000c5f0000c13d000009a501000041000000000010043f00000011010000390000155d0000013d0000006501000039000000000101041a0000095a021001970000000001000411000000000021004b00000a7d0000c13d00010a7d0000003d0000224c0000013d000000cb02000039000000000302041a0000095a02300198000000330400003900000ca80000c13d000000000204041a000000000112013f0000095a0010019800000e2f0000c13d000000400400043d0000097a013001970000001505000029000000000151019f000000cb02000039000000000012041b0000091d0040009c001300000004001d0000091d010000410000000001044019000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d02000039000000020300003900000998040000412470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001200000001001d0024095a0010019b00010aa30000003d000022780000013d000000240440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000012010000290000095a021001970000099901000041000000130300002900000000001304350000000401300039000000150300002900000000003104350000000001000414000000040020008c00000ab90000613d0000002404000039000000130300002900010ab80000003d000022940000013d00000d620000613d00010abb0000003d000024570000013d00010abd0000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c000004240000a13d00000cf20000013d247018d60000040f000000cf01000039000000000101041a0000099401100197000009950010009c00000cd70000c13d000009c40100004100000f180000013d000000000204041a0000095a022001970000000004000411000000000024004b00000ad70000c13d000000140200008a0000000002200031000000000221034f000000000202043b0000006004200270000000cf02000039000000000202041a0000095a02200198000000330500003900000cea0000c13d000000000205041a000000000242013f0000095a0020019800000e2f0000c13d0000000402100370000000000502043b0000095a0050009c00000cf20000213d000000cd04000039000000000204041a0000097a03200197000000000353019f000000000034041b0000002401100370000000000601043b0000ffff0060008c00000cf20000213d0000095c01200197000000a0026002100000095d02200197000000000121019f000000000151019f000000cd02000039000000000012041b000000400100043d0000091d0010009c001400000001001d0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d0200003900000003030000390000097c040000412470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a00000002020003670000000403200370000000000303043b001300000003001d0000095a0030009c00000cf20000213d0000002402200370000000000202043b001200000002001d0000ffff0020008c00000cf20000213d0011095a0010019b001c00110000002d00010b160000003d000022780000013d0000001c0440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000014020000290000002401200039000000120300002900000000003104350000097d01000041000000000012043500000004012000390000001302000029000000000021043500000000010004140000001102000029000000040020008c00000e870000613d0000004404000039000000110200002900000e830000013d247018460000040f000000400100043d000000000200001900000b4f0000013d000000400200043d0000001001200029001000000002001d00010b350000003d000023fb0000013d000009620010009c0000155a0000213d00000001002001900000155a0000c13d000000400010043f00000010010000290000000f02000029000000000421043600000060010000390000000002000019000000130020006c00000cf30000813d00000000034200190000000000130435000000200220003900000b3f0000013d0000000001e2016f000000a00010043f000000c001000039000000400010043f0000008002000039001500000001001d247016e20000040f0000001503000029000000000231004900000000010300190000000003000019247022050000040f000000400100043d0000002002000039000000000221043600000012030000290000000000320435000009b30030009c00000cf20000213d00000040031000390000001202000029001500050020021a000000150230002900000b630000613d00000011040000290000000204400367000000004504043c0000000003530436000000000023004b00000b5f0000c13d0000000103000039000000000003004b000000000002043500000000021200490000091d0020009c0000091d0200804100000060022002100000091d0010009c0000091d010080410000004001100210000000000112019f00000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d02000039000009b4040000412470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001400000001001d002a095a0010019b00010b7f0000003d000022780000013d0000002a0440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d000000400300043d000000240130003900000012020000290000000000210435000009b5010000410000000000130435000000040130003900000020020000390000000000210435001300000003001d00000044013000390000001503100029000000150000006b00000b990000613d00000011020000290000000202200367000000002402043c0000000001410436000000000031004b00000b950000c13d00000014010000290000095a02100197000000010000008b00000000000304350000000001000414000000040020008c00000ba60000613d00000013050000290000000004530049000000000305001900010ba50000003d000022bb0000013d00000d620000613d00010ba80000003d000024570000013d00010baa0000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d00010bb30000003d000023020000013d0000000f02000029000004290000013d000000000010043f000000200070043f00000040020000390000000001000019001400000003001d001300000004001d2470220f0000040f0000001402000029000000000020043f00010bc00000003d000023340000013d000001000300008a000000000232016f0000001503000029000000000232019f000000000021041b000000800030043f00000000010004140000091d0010009c0000091d01008041000000c0011002100000099c011001c70000800d0200003900000003030000390000099d0400004100000013050000290000001406000029000005fe0000013d000000400200043d000009a3010000410000000000120435001200000002001d00000004012000390000001502000029247019a40000040f000000000301001900000000010004140000001402000029000000040020008c00000be30000613d00000012050000290000000004530049000000000305001900010be20000003d000022bb0000013d00000d620000613d00010be50000003d000022b60000013d0000001202000029000000000223001900010be90000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c000006300000a13d00000cf20000013d000000400300043d000009640100004100000000001304350000000401300039000009650200004100000000002104350000000001000414000000040040008c00000c030000613d000000000204001900000024040000390000002006000039001400000003001d0000001405000029247016340000040f0000001403000029000000000001004b00000d620000613d0000000101000031001400000001001d0000001f01100039000000200200008a00110000002101730000001102300029000000110020006c00000000010000390000000101004039001200000002001d000009620020009c0000155a0000213d00000001001001900000155a0000c13d0000001201000029000000400010043f0000001401000029000009630010009c00000cf20000213d0000001401000029000000200010008c00000cf20000413d000000000103043300010c1c0000003d000022520000013d00000cf20000c13d000000000001004b000000150100002900000a1d0000613d001700000001001d000080020100003900000024030000390000000004000415000000170440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d000000120300002900000044013000390000000a0200002900010c2f0000003d000023860000013d0000096501000041000000000013043500000008010000290000095a011001970000000402300039000000000012043500000000010004140000001502000029000000040020008c0000126c0000613d00000064040000390000001502000029000000120300002900000000050300190000000006000019247016100000040f0014000100000035000000000001004b000012680000c13d0000000303000367000000200100008a000000140200002900000000041201700000001f0520018f000000400100043d000000000241001900000c500000613d000000000603034f0000000007010019000000006806043c0000000007870436000000000027004b00000c4c0000c13d000000000005004b00000c5d0000613d000000000343034f0000000304500210000000000502043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003204350000001402000029247021fd0000040f000000010130008a000000000032004b00000d380000c13d000009a40230009a000000000002041b000000000014041b0000001501000029000000000010043f000000ca0100003900010c6a0000003d0000228b0000013d000000000001041b000000400100043d0000091d0010009c001300000001001d0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d020000390000000303000039000009a704000041000000150500002900000000060000192470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001200000001001d0026095a0010019b00010c840000003d000022780000013d000000260440008a00000005044002100000096002000041247022230000040f000000000001004b000009990000613d00000012010000290000095a02100197000009a80100004100000013040000290000000000140435000000040140003900000015030000290000000000310435000000240140003900000000000104350000000001000414000000040020008c00000c9c0000613d0000004404000039000000130300002900010c9b0000003d000022940000013d00000d620000613d00010c9e0000003d000024570000013d00010ca00000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c000004270000a13d000009990000013d000000400500043d000000440350003900000015040000290000000000430435000009800300004100000000003504350000095a0110019700000004035000390000000000130435000000240150003900000000000104350000000001000414000000040020008c00000cbf0000613d000000640400003900000020060000390000000003050019001300000005001d0000001305000029247016100000040f0000001305000029000000000001004b00000d620000613d00010cc10000003d0000246b0000013d0000000003520019000000000023004b00000000020000390000000102004039000009620030009c0000155a0000213d00000001002001900000155a0000c13d0000000004030019000000400030043f000009630010009c00000cf20000213d000000200010008c00000cf20000413d000000000105043300010cd20000003d000022520000013d00000cf20000c13d000000000001004b0000108f0000c13d000009b10100004100000f180000013d00010cd90000003d0000239e0000013d00000ce80000a13d00010cdc0000003d000022da0000013d000009660020009c0000155a0000213d00010ce00000003d000023070000013d0000095b043001970000000000420435000009960030009c00000f1b0000413d000000000014004b00000f1b0000413d000009c30100004100000f180000013d000009c20100004100000f180000013d000000400600043d0000097905000041001400000006001d00000000005604350000000401100370000000000101043b0000095a0010009c00000d4f0000a13d000023320000013d000d00000004001d00000000020000190000000f0020006c00000e310000813d0000000503200210001400000003001d0000000e01300029001300000001001d0000000201100367000000000101043b001500000002001d24701ad70000040f000000150300002900000010020000290000000002020433000000000032004b00000de30000a13d00000014040000290000000d02400029000000000012043500000010010000290000000001010433000000000031004b00000de30000a13d00000013010000290000000201100367000000000101043b24701bf70000040f000000150300002900000011020000290000000002020433000000000032004b00000de30000a13d000000140400002900000012024000290000000000120435000000010130003900000011020000290000000002020433000000000032004b000000000201001900000cf50000213d00000de30000013d000000030400036700010d210000003d000022460000013d00000d6c0000613d000000000704034f000000000801001900010d260000003d000023150000013d00000d240000c13d00000d6c0000013d0000099b0100004100000f180000013d0000001501000029000000000214013f0000095a00200198000000000204001900000d340000613d24701c330000040f00000000040004110000006503000039000000000001004b00000ec40000613d000000140000006b00000da10000c13d000009c00100004100000f180000013d000000000012004b00000de30000a13d000009a40120009a000000000101041a000009a40230009a000000000012041b000000000010043f000000ca01000039000000200010043f00000040020000390000000001000019001300000003001d2470220f0000040f0000001302000029000000000021041b000000c901000039000000000101041a000000000001004b00000f350000c13d000009a501000041000000000010043f00000031010000390000155d0000013d0000095a0440019700000014070000290000004405700039000000000045043500000024047000390000000000340435000000040370003900000000001304350000000001000414000000040020008c00000dc80000613d0000006404000039000000200600003900000000030700190000000005070019247016340000040f0000001407000029000000000001004b00000dc80000c13d0000000304000367000000010200003100010d660000003d000022460000013d00000d6c0000613d000000000704034f000000000801001900010d6b0000003d000023150000013d00000d690000c13d000000000006004b00000d740000613d000000000454034f0000000305600210000000000603043300010d730000003d000024630000013d0000000000430435247021fd0000040f000400000003001d000000000102041a0000095a011001970000000002000411000000000012004b00000d7e0000c13d00010d7d0000003d000023510000013d0013006000100278000000400100043d001400000001001d000009660010009c0000155a0000213d00000014020000290000004001200039000000400010043f000000010100003900000000021204360000000a01000029001100000002001d0000000000120435000000400100043d000300000001001d000009660010009c0000155a0000213d00000003020000290000004001200039000000400010043f000000010100003900000000011204360000000902000029000200000001001d000000000021043500010d980000003d0000244d0000013d00010d9a0000003d000022850000013d001500090010007400000ffa0000813d0000096f01000041000000000010043f00000004020000390000000001000019247021fd0000040f000000000103041a0000095a01100197001000000004001d000000000014004b00000da90000c13d00010da80000003d000023510000013d0010006000100278000000400100043d000f00000001001d000009660010009c0000155a0000213d0000000f030000290000004001300039000000400010043f00000020013000390000001302000029000000000021043500000001010000390000000000130435000000400100043d000e00000001001d000009660010009c0000155a0000213d0000000e020000290000004001200039000000400010043f000000010100003900000000011204360000001202000029000000000021043500010dc20000003d000024430000013d00010dc40000003d000022850000013d000d001200100074000010920000813d0000096f0100004100000f180000013d00010dca0000003d000022b60000013d000000000273001900010dcd0000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d000000200010008c00000cf20000413d0000001401000029000000000101043300010dda0000003d000022520000013d00000cf20000c13d000000000001004b000010d40000c13d000009900100004100000f180000013d00000015020000290000000002020433000000000002004b00000e990000c13d000009a501000041000000000010043f00000032010000390000155d0000013d00010de90000003d000023260000013d000006640000613d000000000100043d0000000102000031000000200020008c000006640000413d000000000001004b000006640000613d0000006501000039000000000101041a0000095a011001970000000004000411000000000014004b00000df90000c13d00010df80000003d000023510000013d0000006004100270000000cf01000039000000000101041a0000095a0310019800000f390000c13d0000003302000039000000000202041a000000000242013f0000095a0020019800000e2f0000c13d000000400200043d001300000002001d0000097a011001970000001505000029000000000151019f000000cf02000039000000000012041b00000013010000290000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d0200003900000002030000390000098d040000412470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001200000001001d0029095a0010019b00010e1f0000003d000022780000013d000000290440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000012010000290000095a021001970000098e0100004100000013030000290000000000130435000000040130003900000015030000290000000000310435000000000100041400000ab20000013d000009c90100004100000f180000013d000000400200043d00000040010000390000000001120436000f00000001001d0000001101000029000000000301043300000040012000390000000000310435001300000002001d0000006002200039001200000003001d0000000501300210001500000002001d00000000022100190000000004000019000000130120006a001400000004001d000000120040006c00000e510000813d000000600110008a00000015030000290000000003130436001500000003001d00000011010000290000002001100039001100000001001d0000000001010433247017010000040f00000014040000290000000104400039000000000201001900000e400000013d0000000f03000029000000000013043500000010010000292470171b0000040f000000130300002900000b4d0000013d000000cf02000039000000000102041a0000097a01100197000000000012041b00000014010000290000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d0200003900000002030000390000098d0400004100000000050000192470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001300000001001d0021095a0010019b00010e720000003d000022780000013d000000210440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000013010000290000095a021001970000098e0100004100000014030000290000000000130435000000040130003900000000000104350000000001000414000000040020008c00000e870000613d0000002404000039000000140300002900010e860000003d000022940000013d00000d620000613d00000001010000310000001f02100039000000200300008a000000000332016f000000140230002900010e8e0000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d00010e970000003d000023020000013d0000001502000029000004290000013d00000014020000290000000000210435000000d001000039000000000101041a001400000001001d002d095a0010019b00010ea10000003d000022780000013d0000002d0440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000014010000290011095a0010019b000000400300043d000009ca010000410000000000130435000000040130003900000040020000390000000000210435001400000003001d000000440230003900000013060000290000000003060433000000000032043500000000040000190000002002200039000000000034004b00000f860000813d000000200660003900000000050604330000000000520435000000010440003900000eb50000013d000000130120014f0000095a0010019800000ec60000613d000000130100002924701c330000040f000000000001004b00000ec60000c13d000009ba0100004100000f180000013d000000100100002900000000010104330000000f020000290000000002020433000000000021004b00000f170000c13d0000000e0000006b000000650200003900000d360000613d000000000202041a0000095a022001970000000003000411000000000023004b00000ed90000c13d000000140200008a00000000022000310000000202200367000000000202043b000b0060002002780000000f02000029000d00200020003d0000001002000029000c00200020003d00000000020000190000010303000039000000000012004b0000004004000039000011d80000813d0000000f010000290000000001010433000000000021004b00000de30000a13d001100000002001d00000005012002100000000c0210002900000000050204330000000d011000290000000001010433001500000001001d001400000005001d000000000050043f000000200030043f000000000100001900000000020400192470220f0000040f0000001302000029000000000020043f00010ef70000003d000022850000013d001200150010007400000dc60000413d0000001401000029000000000010043f000001030100003900010efe0000003d0000232d0000013d0000001302000029000000000020043f00010f020000003d0000232d0000013d0000001202000029000000000021041b0000001401000029000000000010043f000001030100003900010f090000003d0000232d0000013d0000000e0200002900010f0c0000003d000024160000013d000000150320014f000000000201041a000000000032004b00000a710000213d0000001502200029000000000021041b000000110200002900000001022000390000001001000029000000000101043300000ede0000013d000009bb01000041000000000010043f00000971010000410000247200010430001300000004001d000000400300043d000009690030009c0000155a0000213d0000002001300039000000400010043f00000000000304350000001501000029000000140200002924701dae0000040f0000001401000029000000000010043f000001380100003900010f2a0000003d0000228b0000013d00000013020000290000000102200039000000000301041a0000096c033001970000095b04200197000000000343019f000000000031041b00000097010000390000000103000039000000000031041b000002440000013d0000000003010019000000010110008a000000c90400003900000c620000013d0000095a01400197000000400500043d00000024045000390000000000140435000009b0010000410000000000150435001200000005001d0000000401500039000000150400002900000000004104350000000001000414000000040030008c00000f6a0000613d00000044040000390000002006000039000000000203001900000012030000290000000005030019247016340000040f0000000102000031000000000001004b00000f6a0000c13d000000030400036700010f520000003d000022460000013d00000d6c0000613d000000000704034f000000000801001900010f570000003d000023150000013d00000f550000c13d00000d6c0000013d000000400100043d0000002002000039000000000221043600000010060000290000000003060433000000000032043500000000040000190000002002200039000000000034004b00000f680000813d000000200660003900000000050604330000000000520435000000010440003900000f600000013d000000000212004900000b4f0000013d0000001f01200039000000200300008a000000000131016f0000001203100029000000000013004b00000000010000390000000101004039001300000003001d000009620030009c0000155a0000213d00000001001001900000155a0000c13d0000001301000029000000400010043f000009630020009c00000cf20000213d000000200020008c00000cf20000413d0000001201000029000000000101043300010f800000003d000022520000013d00000cf20000c13d000000000001004b00000cd50000613d000000cf01000039000000000101041a00000e040000013d000000000112004900000014030000290000002403300039000000000013043500000015010000292470171b0000040f000000000201001900000000010004140000001103000029000000040030008c00000f970000613d00000014030000290000000004320049000000110200002900010f960000003d000022940000013d00000d620000613d00000001010000310000001f02100039000000200300008a000000000332016f000000140230002900010f9e0000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d00000000010004150000001202000029000004290000013d000e095a0010019b0000000005000019000000130050006c0000118c0000813d000000110050006c00000de30000813d0000000601500210000000100610002900000020016000390000000202000367000000000112034f000000000101043b0000ffff0010008c00000cf20000213d000027110010008c000008510000813d00000005035002100000001207300029000000000372034f000000000303043b000000400800043d0000098f04000041000000000048043500000004048000390000000000340435000000000262034f000000000202043b0000095a0020009c00000cf20000213d00000064038000390000000e040000290000000000430435000000440380003900000000001304350000002401800039000000000021043500000000010004140000000f02000029000000040020008c001500000005001d001400000006001d00000fde0000613d0000000f020000290000000003080019000000840400003900000000050800190000002006000039000d00000007001d000c00000008001d247016340000040f0000000c080000290000000d07000029000000000001004b00000d620000613d00010fe00000003d000022b60000013d000000000283001900010fe30000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d000000200010008c00000cf20000413d000000000108043300010fef0000003d000022520000013d00000cf20000c13d000000000001004b00000ddd0000613d000000020170036700010ff50000003d000023bb0000013d0000001402000029247018eb0000040f0000001505000029000000010550003900000faa0000013d00010ffc0000003d0000244d0000013d000000200010043f000000000100001900000040020000392470220f0000040f0000001502000029000000000021041b000000400100043d0000002002100039000000090300002900000000003204350000000a0200002900000000002104350000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f00000967011001c70000800d020000390000000403000039000009680400004100000013050000290000000c0600002900000000070000192470223c0000040f000000010020019000000cf20000613d000000400100043d000009690010009c0000155a0000213d0000002002100039000000400020043f00000000000104350000001301000029000b095a0010019b00000014010000290000000001010433001000000001001d0000000002000019000000100020006c000013c10000813d00000014010000290000000001010433000000000021004b00000de30000a13d001500000002001d00000005012002100000001101100029001300000001001d0000000001010433247019280000040f000000000001004b0000108c0000613d0000000004010019000000400300043d0000096401000041000000000013043500000004013000390000096d0200004100000000002104350000000001000414000000040040008c001200000004001d000010470000613d000110410000003d0000238b0000013d000f00000003001d247016340000040f0000000f030000290000001204000029000000000001004b00000d620000613d000110490000003d000022990000013d000009620050009c0000155a0000213d00000001001001900000155a0000c13d000000400050043f000009630070009c00000cf20000213d000000200070008c00000cf20000413d0000000001030433000110550000003d000022520000013d00000cf20000c13d000000000001004b0000108c0000613d000d00000006001d000f00000005001d000e00000007001d00000014010000290000000001010433000000150010006c00000de30000a13d00000013010000290000000001010433001300000001001d001b00000004001d00000000040004150000001b0440008a0000000504400210000080020100003900000960020000410000002403000039247022230000040f000000000001004b000009990000613d0000000f0300002900000064013000390000001302000029000110710000003d000023860000013d0000096e01000041000110740000003d000024370000013d0000004401300039000000000001043500000000010004140000001202000029000000040020008c0000000e050000290000000d04000029000010830000613d0001107e0000003d0000230e0000013d000014a50000613d0000001f01500039000000200200008a000000000421016f0000000f03000029000110850000003d0000241d0000013d000009620010009c0000155a0000213d00000001002001900000155a0000c13d000000400010043f000009630050009c00000cf20000213d00000015020000290000000102200039000010260000013d000000cb01000039000000000301041a00000a870000013d000110940000003d000024430000013d000110960000003d0000232d0000013d0000000d02000029000000000021041b0000001301000029000000000010043f0000010301000039000000200010043f000000000100001900000040020000392470220f0000040f0000001402000029000110a20000003d000024160000013d000000120320014f000000000201041a000000000032004b00000a710000213d00000012030000290000000002320019000000000021041b000000400100043d00000020021000390000000000320435000000130200002900000000002104350000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f00000967011001c70000800d02000039000000040300003900000968040000410000001005000029000000150600002900000014070000292470223c0000040f000000010020019000000cf20000613d0000001001000029000000150200002900000014030000290000000f040000290000000e0500002924701c660000040f003000140000002d000080020100003900000024030000390000000004000415000000300440008a00000005044002100000096002000041247022230000040f000000400200043d000f00000002001d000000000001004b0000127a0000c13d0000000f0100002900000b2e0000013d000000020100036700000ae00000013d0000001401000029000110d90000003d000022d20000013d0000096c022001970000001004000029000010e10000013d0000001401000029000110df0000003d000022d20000013d0000096c022001970000000f040000290000095b03400197000000000232019f000000000021041b00000097010000390000000102000039000000000021041b000000400100043d0000000000410435000007a30000013d0000000f010000290000000e020000292470196f0000040f000000400a00043d00140000000a001d000009a000a0009c0000155a0000213d0013095a0010019b000000140c000029000001c001c00039000000400010043f0000016001c00039000000010a0000390000000000a104350000001501000029000009a101100197000001400ac0003900000000001a04350000095a012001970000006002c000390000000000120435000009a1013001970000002002c000390000000000120435000009a1014001970000004002c000390000000000120435000009a2015001970000012002c000390000000000120435000009a101600197000000e002c000390000000000120435000009a1017001970000008002c000390000000000120435000009a1018001970000010002c0003900000000001204350000095a01900197000000c002c00039000000000012043500000000010004100000095a01100197000111180000003d000023a30000013d002800130000002d0001111b0000003d000022780000013d000000280440008a00000005044002100000096002000041247022230000040f000000000001004b000009990000613d000000400200043d000009a3010000410000000000120435001200000002001d00000004012000390000001402000029247019a40000040f000000000201001900000000010004140000001303000029000000040030008c000011330000613d000000120300002900000000043200490000001302000029000111320000003d000022940000013d00000d620000613d000111350000003d000022b60000013d0000001202300029000111380000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c000005df0000a13d00000cf20000013d000000400100043d001500000001001d0000000f0200002900000010030000290000000d040000290000000e05000029247018b30000040f000000150200002900000000012100490000091d0010009c0000091d0100804100000060011002100000091d0020009c0000091d020080410000004002200210000000000121019f00000000020004140000091d0020009c0000091d02008041000000c002200210000000000121019f0000097b011001c70000800d0200003900000001030000390000097e040000412470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001500000001001d001d095a0010019b000111620000003d000022780000013d0000001d0440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000015010000290014095a0010019b000000400200043d0000097f010000410000000000120435001500000002001d00000004012000390000000f0200002900000010030000290000000d040000290000000e05000029247018b30000040f000000000401001900000000010004140000001403000029000000040030008c0000117f0000613d0000000002030019000000150300002900000000043400490001117e0000003d000022940000013d00000d620000613d000111810000003d000022630000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d0001118a0000003d000023020000013d0000000a02000029000004290000013d000000400100043d001500000001001d0000001202000029000000130300002900000010040000290000001105000029247019000000040f000000150200002900000000012100490000091d0010009c0000091d0100804100000060011002100000091d0020009c0000091d020080410000004002200210000000000121019f00000000020004140000091d0020009c0000091d02008041000000c002200210000000000121019f0000097b011001c70000800d02000039000000010300003900000991040000412470223c0000040f000000010020019000000cf20000613d000000d001000039000000000101041a001500000001001d0022095a0010019b000111ae0000003d000022780000013d000000220440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000015010000290014095a0010019b000000400200043d00000992010000410000000000120435001500000002001d00000004012000390000001202000029000000130300002900000010040000290000001105000029247019000000040f000000000401001900000000010004140000001403000029000000040030008c000011cb0000613d000000000203001900000015030000290000000004340049000111ca0000003d000022940000013d00000d620000613d000111cd0000003d000022630000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d000111d60000003d000023020000013d0000000b02000029000004290000013d000000400100043d0000000003410436000000400210003900000010050000290000000004050433000000000042043500000000060000190000002002200039000000000046004b000011e70000813d0000002005500039000000000705043300000000007204350000000106600039000011df0000013d000000000412004900000000004304350000000f040000290000000003040433000000000032043500000000050000190000002002200039000000000035004b000011f50000813d0000002004400039000000000604043300000000006204350000000105500039000011ed0000013d00000000021200490000091d0020009c0000091d0200804100000060022002100000091d0010009c0000091d010080410000004001100210000000000112019f00000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d020000390000000403000039000009bc040000410000000b0500002900000013060000290000000e070000292470223c0000040f000000010020019000000cf20000613d0000000b0100002900000013020000290000000e0300002900000010040000290000000f0500002924701c660000040f0030000e0000002d000080020100003900000024030000390000000004000415000000300440008a00000005044002100000096002000041247022230000040f000000400200043d001500000002001d000000000001004b000013560000c13d000000150100002900000b2e0000013d0000000c010000290000000b02000029247019eb0000040f001300000001001d001200000004001d000000400100043d001400000001001d0000095e0010009c0000155a0000213d0011095a0030019b0000001405000029000000c001500039000000400010043f0000006001500039000000010300003900000000003104350000095a012001970000004002500039000000000012043500000015010000290000095f011001970000002002500039000000000012043500000000010004100000095a011001970000000000150435000000a001500039000000000001043500000080015000390000000000010435002700110000002d000112410000003d000022780000013d000000270440008a00000005044002100000096002000041247022230000040f000000000001004b000009990000613d000000400200043d00000961010000410000000000120435001000000002001d000000040120003900000014020000290000001303000029000000120400002924701a220000040f000000000201001900000000010004140000001103000029000000040030008c0000125b0000613d0000001003000029000000000432004900000011020000290001125a0000003d000022940000013d00000d620000613d0001125d0000003d000022b60000013d0000001002300029000112600000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c000005e10000a13d00000cf20000013d00000014010000290000001f01100039000000200200008a001100000021017300000011020000290000001201200029000112700000003d000023fb0000013d000009620010009c0000155a0000213d00000001002001900000155a0000c13d000000400010043f0000001401000029000009630010009c000000650200003900000a2e0000a13d00000cf20000013d0000000f030000290001127d0000003d000023f60000013d000000120200002900000000002104350000004401300039000000130200002900000000002104350000002401300039000000150200002900000000002104350000097601000041000000000013043500000010010000290000095a0110019700000004023000390000000000120435000000a4023000390000001101000029247016ce0000040f000000000201001900000000010004140000001403000029000000040030008c0000129b0000613d0000000f030000290000000004320049000000200600003900000014020000290000000005030019247016100000040f000000000001004b000013970000613d00000001020000310001129e0000003d000023eb0000013d0000000f01300029000112a10000003d000023e70000013d000009620010009c0000155a0000213d00000001003001900000155a0000c13d000000400010043f000009630020009c00000cf20000213d000000200020008c00000cf20000413d0000000f020000290000000002020433000009770020019800000cf20000c13d0000097802200197000009760020009c00000b2e0000613d000013bf0000013d000000110000006b0000000001000019000012b80000613d00000010010000290000000201100367000000000101043b0000001104000029000112bb0000003d0000231e0000013d000012cb0000013d000000110030006c000012c80000813d00000011030000290000000303300210000000f80330018f000000010400008a000000000334022f000000000343013f000000000252034f000000000202043b000000000232016f000000000021041b0000001101000029000000010110021000000001011001bf0000013402000039000000000012041b000000d001000039000000000101041a000d00000001001d002c095a0010019b000112d30000003d000022780000013d0000002c0440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d000000400400043d000009c1010000410000000000140435000000640140003900000015030000290000000000310435000000040140003900000060020000390000000000210435000000200200008a00000000052301700000001f0630018f000f00000004001d0000008403400039000000000453001900000002020003670000001407200360000012f10000613d000000000807034f0000000009030019000000008a08043c0000000009a90436000000000049004b000012ed0000c13d000000000006004b000012f70000613d000000000557034f0000000306600210000112f70000003d0000236a0000013d0000001505000029000000000453001900000000000404350000001f04500039000000200600008a000000000464016f000000000343001900000000041300490000000f050000290000002405500039000000000045043500000012052003600000001304000029000000000343043600000000066401700000001f0740018f00000000046300190000130f0000613d000000000805034f0000000009030019000000008a08043c0000000009a90436000000000049004b0000130b0000c13d000000000007004b000013150000613d000000000565034f0000000306700210000113150000003d0000236a0000013d0000001305000029000000000453001900000000000404350000001f04500039000000200500008a000000000454016f000000000343001900000000011300490000000f040000290000004404400039000000000014043500000010042003600000001101000029000000000313043600000000055101700000001f0610018f00000000015300190000132d0000613d000000000204034f0000000007030019000000002802043c0000000007870436000000000017004b000013290000c13d0000000d020000290000095a02200197000000000006004b000013370000613d000000000454034f00000003056002100000000006010433000113360000003d000024630000013d0000000000410435000000110130002900000000000104350000000001000414000000040020008c000013470000613d00000011040000290000001f04400039000000200500008a000000000454016f0000000f05000029000000000454004900000000043400190000000003050019000113460000003d000022bb0000013d00000d620000613d000113490000003d000022b60000013d0000000f023000290001134c0000003d000022900000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d00000000010004150000000e02000029000004290000013d00000015030000290000004401300039000000a0020000390000000000210435000000240130003900000013020000290000000000210435000009bd0100004100000000001304350000000b010000290000095a0210019700000004013000390000000000210435000000a40230003900000010030000290000000003030433000000000032043500000000040000190000002002200039000000000034004b000013720000813d00000010050000290000002005500039001000000005001d000000000505043300000000005204350000000104400039000013680000013d00000000031200490000001504000029000000640440003900000000003404350000000f030000290000000003030433000000000032043500000000040000190000002002200039000000000034004b000013840000813d0000000f050000290000002005500039000f00000005001d0000000005050433000000000052043500000001044000390000137a0000013d00000000011200490000001503000029000000840330003900000000001304350000000a01000029247016ce0000040f000000000201001900000000010004140000000e03000029000000040030008c000013a90000613d0000001503000029000000000432004900000020060000390000000e020000290000000005030019247016100000040f000000000001004b000013a90000c13d0000000101000031000000040010008c000013a70000413d000000000100043d00000977011001970000000302000367000000000202043b0000097802200197000000000112019f000000000010043f0000097801100197000009750010009c000013a70000c13d2470212f0000040f000000000001004b000014b30000c13d000009be0100004100000f180000013d0000000102000031000113ac0000003d000023eb0000013d0000001501300029000113af0000003d000023e70000013d000009620010009c0000155a0000213d00000001003001900000155a0000c13d000000400010043f000009630020009c00000cf20000213d000000200020008c00000cf20000413d00000015020000290000000002020433000009770020019800000cf20000c13d0000097802200197000009bd0020009c00000b2e0000613d000009bf0100004100000f180000013d000000d001000039000000000101041a0015095a0010019b0000001001000029000000010010008c0000146c0000c13d00000014010000290000000001010433000000000001004b00000de30000613d00000003010000290000000001010433000000000001004b00000de30000613d00000011010000290000000001010433001400000001001d00000002010000290000000001010433001300000001001d001900150000002d000113d80000003d000022780000013d000000190440008a00000005044002100000096002000041247022230000040f000000000001004b000009990000613d000000400300043d00000084013000390000001302000029000000000021043500000064013000390000001402000029000113e60000003d000023860000013d0000096b01000041000113e90000003d000024370000013d001400000003001d0000004401300039000000000001043500000000010004140000001502000029000000040020008c000015240000c13d0000000102000031000015350000013d0000000d010000290000000001010433000113f60000003d000022520000013d00000cf20000c13d0000000c010000290000000001010433000e00000001001d0000095a0010009c00000cf20000213d000000400100043d001500000001001d000009660010009c0000155a0000213d000114020000003d000022e20000013d000008510000213d000114050000003d0000243c0000013d0000095a021001970000000001000411000000000021004b0000140b0000c13d0001140b0000003d0000224c0000013d0000000f02000029000f095a0020019b0001140f0000003d000022f20000013d0000095a011001980000141b0000613d000000cd04000039000000000204041a0000095c022001970000000d030000290000000003030433000000a0033002100000095d03300197000000000232019f000000000112019f000000000014041b0001141d0000003d000023740000013d0000097a01100197000114200000003d000023ef0000013d000000120020006c000015390000813d00000014010000290000000001010433000000000021004b00000de30000a13d0000000501200210001500000002001d000000130110002900000000010104330000095a01100197247018930000040f00000015020000290000000102200039000014200000013d0000000d010000290000000001010433000114330000003d000022520000013d00000cf20000c13d0000000c010000290000000001010433000e00000001001d0000095a0010009c00000cf20000213d000000400100043d001500000001001d000009660010009c0000155a0000213d0001143f0000003d000022e20000013d000008510000213d000114420000003d0000243c0000013d0000095a021001970000000001000411000000000021004b000014480000c13d000114480000003d0000224c0000013d0000000f02000029000f095a0020019b0001144c0000003d000022f20000013d0000095a01100198000014580000613d000000cd04000039000000000204041a0000095c022001970000000d030000290000000003030433000000a0033002100000095d03300197000000000232019f000000000112019f000000000014041b0001145a0000003d000023740000013d0000097a011001970001145d0000003d000023ef0000013d000000120020006c000015560000813d00000014010000290000000001010433000000000021004b00000de30000a13d0000000501200210001500000002001d000000130110002900000000010104330000095a01100197247018930000040f000000150200002900000001022000390000145d0000013d001a00150000002d0001146f0000003d000022780000013d0000001a0440008a00000005044002100000096002000041247022230000040f000000000001004b000009990000613d000000400300043d0000006401300039000000a0020000390001147a0000003d000023860000013d0000096a010000410001147d0000003d000024370000013d00000044023000390000000000020435001300000003001d000000a40230003900000014030000290000000003030433000000000032043500000000040000190000002002200039000000000034004b0000148f0000813d00000014050000290000002005500039001400000005001d000000000505043300000000005204350000000104400039000014850000013d000000000112004900000013030000290000008403300039000000000013043500000003050000290000000001050433000000000012043500000000030000190000002002200039000000000013004b0000149f0000813d0000002005500039000000000405043300000000004204350000000103300039000014970000013d00000000010004140000001503000029000000040030008c000014bd0000c13d0000000102000031000014ce0000013d000114a70000003d000022ca0000013d000014ae0000613d000000000603034f0000000007010019000000006806043c0000000007870436000000000097004b000014aa0000c13d000000000005004b00000d740000613d000114b20000003d000022570000013d247021fd0000040f0000000002010019000000400300043d001500000003001d000009750100004100000000001304350000000401300039247016e20000040f000000150210006a0000001501000029247021fd0000040f0000001303000029000000000432004900000015020000290000000005030019000114c30000003d000023190000013d000014ce0000c13d0000000304000367000114c70000003d000022460000013d00000d6c0000613d000000000704034f0000000008010019000114cc0000003d000023150000013d000014ca0000c13d00000d6c0000013d000114d00000003d000023eb0000013d00000013010000290000000001130019000114d40000003d000023e70000013d000009620010009c0000155a0000213d00000001003001900000155a0000c13d000000400010043f000009630020009c00000cf20000213d00000000010004150000000401100069000000000100000200000009010000290000095b01100197000000060010006b00000a710000413d0000000a01000029000000000010043f0000013801000039000114e70000003d0000228b0000013d0000000503000029000000090230006a0000095b02200197000000000301041a0000096c03300197000000000223019f000000000021041b000000d001000039000000000101041a001500000001001d0018095a0010019b000114f40000003d000022780000013d000000180440008a00000005044002100000096002000041247022230000040f000000000001004b00000cf20000613d00000015010000290000095a02100197000000400400043d00000084014000390000000903000029000000000031043500000064014000390000000a03000029000000000031043500000024014000390000000c0300002900000000003104350000096b01000041000000000014043500000008010000290000095a0110019700000004034000390000000000130435001500000004001d000000440140003900000000000104350000000001000414000000040020008c000015170000613d000000a4040000390000001503000029000115160000003d000022940000013d00000d620000613d000115190000003d000022630000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d000115220000003d000023020000013d0000000702000029000004290000013d000000a4040000390000001502000029000000140300002900000000050300190001152a0000003d000023190000013d000015350000c13d00000003040003670001152e0000003d000022460000013d00000d6c0000613d000000000704034f0000000008010019000115330000003d000023150000013d000015310000c13d00000d6c0000013d000115370000003d000023eb0000013d0000001401000029000014d10000013d0001153b0000003d000024300000013d000009620010009c0000155a0000213d0001153f0000003d000022bf0000013d0000032b0000c13d000000150200002924701a4c0000040f0000001501000029000000200010008c000015790000413d0000013401000039000000000010043f000000200100008a000000150210017f0000002003000039000009810100004100000000040000190000000906000029000000000024004b0000000005630019000015830000813d0000000005050433000000000051041b0000002004400039000000200330003900000001011000390000154d0000013d000115580000003d000024300000013d000009620010009c000015600000a13d000009a501000041000000000010043f0000004101000039000000040010043f000009a6010000410000247200010430000115620000003d000022bf0000013d0000032b0000c13d000000150200002924701a4c0000040f0000001501000029000000200010008c000015ce0000413d0000013401000039000000000010043f000000200100008a000000150210017f0000002003000039000009810100004100000000040000190000000906000029000000000024004b0000000005630019000015d80000813d0000000005050433000000000051041b000000200440003900000020033000390000000101100039000015700000013d000000150000006b00000000010000190000157f0000613d0000000901000029000000200110003900000000010104330000001504000029000115820000003d0000231e0000013d0000158a0000013d000000150020006c000015870000813d000115870000003d000023560000013d0000001501000029000000010110021000000001011001bf0000013402000039000000000012041b001f000e0000002d0001158f0000003d000022780000013d0000001f0440008a00000005044002100000096002000041247022230000040f000000000001004b000000000200041000000cf20000613d000000400300043d000009880100004100000000001304350000095a01200197001500000003001d0000000402300039000000000012043500000000010004140000000e02000029000000040020008c000015a70000613d00000024040000390000000e020000290000001503000029000115a60000003d000022940000013d00000d620000613d000115a90000003d000022630000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d000000d002000039000000000102041a0000097a011001970000000e011001af000000000012041b00000000010004150000000b0110006900000000010000020000ff010100008a000000000200041a000000000112016f000000000010041b000000400100043d000000010300003900000000003104350000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f00000989011001c70000800d020000390000098a040000412470223c0000040f00000001002001900000160d0000c13d00000cf20000013d000000150000006b0000000001000019000015d40000613d0000000901000029000000200110003900000000010104330000001504000029000115d70000003d0000231e0000013d000015df0000013d000000150020006c000015dc0000813d000115dc0000003d000023560000013d0000001501000029000000010110021000000001011001bf0000013402000039000000000012041b001e000e0000002d000115e40000003d000022780000013d0000001e0440008a00000005044002100000096002000041247022230000040f000000000001004b000000000200041000000cf20000613d000000400300043d000009880100004100000000001304350000095a01200197001500000003001d0000000402300039000000000012043500000000010004140000000e02000029000000040020008c000015fc0000613d00000024040000390000000e020000290000001503000029000115fb0000003d000022940000013d00000d620000613d000115fe0000003d000022630000013d000009620020009c0000155a0000213d00000001003001900000155a0000c13d000000400020043f000009630010009c00000cf20000213d000000d002000039000000000102041a0000097a011001970000000e011001af000000000012041b00000000010004150000000b01100069000000000100000200000000010004150000001102000029000004290000013d0003000000000002000300000006001d000200000005001d0000091d0030009c0000091d0300804100000040033002100000091d0040009c0000091d040080410000006004400210000000000334019f0000091d0010009c0000091d01008041000000c001100210000000000113019f2470223c0000040f000000020900002900000060031002700000091d03300197000000030030006c000000030400002900000000040340190000001f0540018f000009d00640019800000000046900190000162e0000613d000000000701034f000000007807043c0000000009890436000000000049004b0000162a0000c13d000000010220018f000000000005004b000016330000613d000116330000003d0000233a0000013d000023e30000013d0003000000000002000300000006001d000200000005001d0000091d0030009c0000091d0300804100000040033002100000091d0040009c0000091d040080410000006004400210000000000334019f0000091d0010009c0000091d01008041000000c001100210000000000113019f247022410000040f000000020900002900000060031002700000091d03300197000000030030006c000000030400002900000000040340190000001f0540018f000009d0064001980000000004690019000016520000613d000000000701034f000000007807043c0000000009890436000000000049004b0000164e0000c13d000000010220018f000000000005004b000016570000613d000116570000003d0000233a0000013d000023e30000013d000009d10020009c000016890000813d00000000040100190000001f01200039000000200600008a000000000161016f0000003f01100039000000000561016f000000400100043d0000000005510019000000000015004b00000000070000390000000107004039000009620050009c000016890000213d0000000100700190000016890000c13d000000400050043f00000000052104360000000007420019000000000037004b0000168f0000213d00000000066201700000001f0720018f00000002044003670000000003650019000016790000613d000000000804034f0000000009050019000000008a08043c0000000009a90436000000000039004b000016750000c13d000000000007004b000016860000613d000000000464034f0000000306700210000000000703043300000000076701cf000000000767022f000000000404043b0000010006600089000000000464022f00000000046401cf000000000474019f000000000043043500000000022500190000000000020435000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a6010000410000247200010430000023320000013d0004000000000002000000000201041a000000010320019000000001052002700000007f0550618f0000001f0050008c00000000040000390000000104002039000000000043004b000016c40000c13d000000400400043d0000000006540436000000000003004b000016b20000613d000400000004001d000000000010043f00000020020000390000000001000019000300000005001d000200000006001d2470220f0000040f0000000206000029000000030500002900000000020000190000000003260019000000000052004b000016b00000813d000000000401041a000000000043043500000020022000390000000101100039000016a80000013d0000000404000029000016b60000013d000001000100008a000000000112016f0000000000160435000000400340003900000000014300490000001f01100039000000200200008a000000000221016f0000000001420019000116bd0000003d000023fb0000013d000009620010009c000016c80000213d0000000100200190000016c80000c13d000000400010043f0000000001040019000000000001042d000009a501000041000000000010043f0000002201000039000016cb0000013d000009a501000041000000000010043f0000004101000039000000040010043f000009a60100004100002472000104300000002004100039000000000301043300000000013204360000000002000019000000000032004b000016da0000813d00000000051200190000000006240019000000000606043300000000006504350000002002200039000016d20000013d000016dd0000a13d000000000213001900000000000204350000001f02300039000000200300008a000000000232016f0000000001210019000000000001042d0000000003020019000000200200003900000000022104360000000001030019247016ce0000040f000000000001042d000009630010009c000017000000213d000000230010008c000017000000a13d00000002020003670000000403200370000000000303043b000009620030009c000017000000213d0000002304300039000000000014004b000017000000813d0000000404300039000000000242034f000000000202043b000009620020009c000017000000213d000000240330003900000005042002100000000004340019000000000014004b000017000000213d0000000001030019000000000001042d000023320000013d00040000000000020000000003020019000100000002001d000400000001001d0000000021010434000300000002001d00000080020000390000000002230436000200000002001d0000008002300039247016ce0000040f00000003020000290000000002020433000000020300002900000000002304350000000404000029000000400240003900000000020204330000000105000029000000400350003900000000002304350000006002500039000000600340003900000000030304330000000000320435000000000001042d0005000000000002000500000001001d00000000010104330000000000120435000200000001001d000000050110021000000000011200190000002003100039000100000002001d000400000002001d0000000002000019000000020020006c000017390000813d000000010130006a000000200110008a000300000002001d00000004020000290000002002200039000400000002001d000000000012043500000005010000290000002001100039000500000001001d00000000010104330000000002030019247016ce0000040f000000030200002900000001022000390000000003010019000017260000013d0000000001030019000000000001042d0000001f03100039000000000023004b0000000004000019000009860400404100000986052001970000098603300197000000000653013f000000000053004b00000000030000190000098603002041000009860060009c000000000304c019000000000003004b000017710000613d0000000204000367000000000314034f000000000503043b000009d10050009c0000176b0000813d00000005065002100000003f036000390000098707300197000000400300043d0000000007730019000000000037004b00000000080000390000000108004039000009620070009c0000176b0000213d00000001008001900000176b0000c13d000000400070043f000000000053043500000000056100190000002005500039000000000025004b000017710000213d00000000020300190000002001100039000000000051004b000017690000813d000000000614034f000000000606043b00000020022000390000000000620435000017610000013d0000000001030019000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a6010000410000247200010430000023320000013d000009630010009c0000177c0000213d000000230010008c0000177c0000a13d00000004010000390000000201100367000000000101043b0000095a0010009c0000177c0000213d000000000001042d000023320000013d0000001f03100039000000000023004b0000000004000019000009860400404100000986052001970000098603300197000000000653013f000000000053004b00000000030000190000098603002041000009860060009c000000000304c019000000000003004b000017af0000613d0000000204000367000000000314034f000000000503043b000009d10050009c000017b00000813d00000005065002100000003f036000390000098707300197000000400300043d0000000007730019000000000037004b00000000080000390000000108004039000009620070009c000017b00000213d0000000100800190000017b00000c13d000000400070043f000000000053043500000000056100190000002005500039000000000025004b000017af0000213d00000000020300190000002001100039000000000051004b000017ad0000813d000000000614034f000000000606043b0000095a0060009c000017af0000213d00000020022000390000000000620435000017a30000013d0000000001030019000000000001042d000023320000013d000009a501000041000000000010043f0000004101000039000000040010043f000009a60100004100002472000104300001000000000002000009630010009c000017d10000213d0000000003010019000000430010008c000017d10000a13d00000002010003670000000402100370000000000202043b000100000002001d0000095a0020009c000017d10000213d0000002402100370000000000402043b000009620040009c000017d10000213d0000002302400039000000000032004b000017d10000813d0000000402400039000000000121034f000000000201043b0000002401400039247016580000040f00000000020100190000000101000029000000000001042d000023320000013d000009630010009c000017e70000213d000000a30010008c000017e70000a13d000000400100043d000009d20010009c000017e80000813d0000004002100039000000400020043f00000002020003670000006403200370000000000303043b0000095a0030009c000017e70000213d00000000033104360000008402200370000000000202043b0000ffff0020008c000017e70000213d0000000000230435000000000001042d000023320000013d000009a501000041000000000010043f0000004101000039000000040010043f000009a60100004100002472000104300004000000000002000009630010009c000018270000213d0000000004010019000000c30010008c000018270000a13d00000002020003670000000401200370000000000101043b000009620010009c000018270000213d0000002303100039000000000043004b000018270000813d0000000403100039000000000232034f000000000202043b00000024011000390000000003040019000400000004001d247016580000040f0000000403000029000300000001001d00000002010003670000002402100370000000000202043b000200000002001d0000004401100370000000000101043b000100000001001d0000095a0010009c000018270000213d0000000001030019247017d20000040f000000040700002900000000040100190000000202000367000000a401200370000000000101043b000009620010009c000018270000213d0000002303100039000000000073004b000018270000813d0000000403100039000000000232034f000000000602043b000009620060009c000018270000213d00000024051000390000000001560019000000000071004b000018270000213d000000030100002900000002020000290000000103000029000000000001042d000023320000013d0000003301000039000000000101041a0000006502000039000000000202041a0000095a032001970000000002000411000000000032004b000018350000c13d000000140200008a00000000022000310000000202200367000000000202043b0000006002200270000000000112013f0000095a00100198000018390000c13d000000000001042d000000400100043d0000004402100039000009d303000041000000000032043500000975020000410000000000210435000000240210003900000020030000390000000000320435000000040210003900000000003204350000006402000039247021fd0000040f00000000060100190000095a011001970000003302000039000000000302041a0000097a04300197000000000114019f000000000012041b000000400100043d0000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000095a053001970000097b011001c70000800d020000390000000303000039000009a9040000412470223c0000040f00000001002001900000185f0000613d000000000001042d000023320000013d00020000000000020000000001000412000200000001001d000100000000003d000080050100003900000044030000390000000004000415000000020440008a0000000504400210000009aa02000041247022230000040f0000097502000041000000400300043d0000000000230435000000040230003900000020040000390000000000420435000000440230003900000024043000390000095a011001970000000005000410000000000015004b0000187e0000c13d0000002c010000390000000000140435000009d40100004100000000001204350000006401300039000009d7020000410000188f0000013d000009ad05000041000000000505041a0000095a05500197000000000015004b000018890000c13d0000000f010000390000000000140435000009d60100004100000000001204350000006402000039000018910000013d0000002c010000390000000000140435000009d40100004100000000001204350000006401300039000009d502000041000000000021043500000084020000390000000001030019247021fd0000040f0003000000000002000300000001001d000118970000003d0000227c0000013d00000000010000190000189a0000613d000000000001042d000000ca050000390000000304000029000000c901000039000000000201041a000009620020009c000018ad0000213d0000000103200039000000000031041b000009d80220009a000000000042041b000000000101041a000200000001001d000000000040043f000000200050043f000118aa0000003d000023930000013d000000000021041b0000000101000039000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a601000041000024720001043000000000060100190000004001000039000000000816043600000040016000390000000000310435000009d90030009c000018d50000813d0000000207000367000000600960003900000005013002120000000001190019000018c40000613d000000000227034f000000002302043c0000000009390436000000000019004b000018c00000c13d000000010000008b00000000026100490000000000280435000000000051043500000000020000190000002001100039000000000052004b000018d40000813d000000000347034f000000000303043b0000095a0030009c000018d50000213d000000000031043500000001022000390000002004400039000018c90000013d000000000001042d000023320000013d0000009701000039000000000201041a000000020020008c000018dd0000613d0000000202000039000000000021041b000000000001042d000000400100043d0000004402100039000009da03000041000000000032043500000024021000390000001f030000390000000000320435000009750200004100000000002104350000000402100039000000200300003900000000003204350000006402000039247021fd0000040f0000000203000367000000000423034f000000000404043b000009950040009c000018ff0000813d000000000501041a0000097a05500197000000000445019f000000000041041b0000002002200039000000000223034f000000000202043b0000ffff0020008c000018ff0000213d000009db03400197000000a0022002100000095d02200197000000000232019f000000000021041b000000000001042d000023320000013d0000004006000039000000000761043600000040061000390000000000360435000009d90030009c000019270000813d0000000206000367000000600810003900000005033002120000000003380019000019100000613d000000000226034f000000002902043c0000000008980436000000000038004b0000190c0000c13d000000010000008b0000000001130049000000000017043500000000015304360000000002000019000000000052004b000019260000813d000000000346034f000000000303043b0000095a0030009c000019270000213d00000000033104360000002007400039000000000776034f000000000707043b0000ffff0070008c000019270000213d0000000000730435000000010220003900000040044000390000004001100039000019150000013d000000000001042d000023320000013d0002000000000002000000cb02000039000000000202041a000200000002001d000000000010043f000000cc01000039000000200010043f000119310000003d000023930000013d0000095a02200197000000000101041a0000095a01100198000000000201c0190000000001020019000000000001042d0000001f03100039000000000023004b0000000004000019000009860400404100000986052001970000098603300197000000000653013f000000000053004b00000000030000190000098603002041000009860060009c000000000304c019000000000003004b0000196e0000613d0000000043010434000009d10030009c000019680000813d0000001f01300039000000200500008a000000000151016f0000003f01100039000000000551016f000000400100043d0000000005510019000000000015004b00000000060000390000000106004039000009620050009c000019680000213d0000000100600190000019680000c13d000000400050043f00000000053104360000000006340019000000000026004b0000196e0000213d0000000002000019000000000032004b000019640000813d000000000652001900000000072400190000000007070433000000000076043500000020022000390000195c0000013d000019670000a13d00000000023500190000000000020435000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a6010000410000247200010430000023320000013d00000000030100190000000001120049000009630010009c000019a30000213d0000011f0010008c000019a30000a13d0000000209000367000000000139034f000000000101043b0000095a0010009c000019a30000213d0000002003300039000000000239034f000000000202043b0000095a0020009c000019a30000213d0000002004300039000000000349034f000000000303043b000009a10030009c000019a30000213d0000002005400039000000000459034f000000000404043b000009a10040009c000019a30000213d0000002006500039000000000569034f000000000505043b000009a20050009c000019a30000213d0000002007600039000000000679034f000000000606043b000009a10060009c000019a30000213d0000002008700039000000000789034f000000000707043b000009a10070009c000019a30000213d000000200a8000390000000008a9034f000000000808043b000009a10080009c000019a30000213d000000200aa000390000000009a9034f000000000909043b0000095a0090009c000019a30000213d000000000001042d000023320000013d00000000430204340000095a0330019700000000033104360000000004040433000009a104400197000000000043043500000040032000390000000003030433000009a10330019700000040041000390000000000340435000000600320003900000000030304330000095a033001970000006004100039000000000034043500000080032000390000000003030433000009a10330019700000080041000390000000000340435000000a0032000390000000003030433000009a103300197000000a0041000390000000000340435000000c00320003900000000030304330000095a03300197000000c0041000390000000000340435000000e0032000390000000003030433000009a103300197000000e004100039000000000034043500000100032000390000000003030433000009a1033001970000010004100039000000000034043500000120032000390000000003030433000009a2033001970000012004100039000000000034043500000140032000390000000003030433000009a1033001970000014004100039000000000034043500000160032000390000000003030433000000000003004b0000000003000039000000010300c0390000016004100039000000000034043500000180032000390000000003030433000000000003004b0000000003000039000000010300c03900000180041000390000000000340435000001a0022000390000000002020433000001a0031000390000000000230435000001c001100039000000000001042d000300000000000200000000030200190000000002120049000009630020009c00001a210000213d0000007f0020008c00001a210000a13d0000000202000367000000000412034f000000000404043b000300000004001d0000095f0040009c00001a210000213d0000002004100039000000000542034f000000000505043b000200000005001d0000095a0050009c00001a210000213d0000002004400039000000000542034f000000000505043b000100000005001d0000095a0050009c00001a210000213d0000002004400039000000000442034f000000000404043b000009620040009c00001a210000213d00000000011400190000001f04100039000000000034004b0000000005000019000009860500804100000986044001970000098606300197000000000764013f000000000064004b00000000040000190000098604004041000009860070009c000000000405c019000000000004004b00001a210000c13d000000000212034f000000000202043b0000002001100039247016580000040f0000000004010019000000030100002900000002020000290000000103000029000000000001042d000023320000013d00000000650204340000095a05500197000000000551043600000000060604330000095f066001970000000000650435000000400520003900000000050504330000095a055001970000004006100039000000000056043500000060052000390000000005050433000000000005004b0000000005000039000000010500c0390000006006100039000000000056043500000080052000390000000005050433000000000005004b0000000005000039000000010500c03900000080061000390000000000560435000000a0022000390000000002020433000000e005100039000001000600003900000000006504350000095f03300197000000c0051000390000000000350435000000000002004b0000000002000039000000010200c039000000a003100039000000000023043500000100021000390000000001040019247016ce0000040f000000000001042d000000200010008c00001a5d0000413d0000013403000039000000000030043f0000001f032000390000000503300270000009dc0330009a000000200020008c00000981030040410000001f011000390000000501100270000009dc0110009a000000000013004b00001a5d0000813d000000000003041b000000010330003900001a580000013d000000000001042d00050000000000020000000035020434000009d10050009c00001aba0000813d00000000060200190000000004010019000000000101041a000000010210019000000001071002700000007f0770618f0000001f0070008c00000000010000390000000101002039000000000012004b00001abe0000c13d000000200070008c000500000004001d000400000005001d000300000006001d00001a890000413d000000000040043f00000020020000390000000001000019000200000003001d000100000007001d2470220f0000040f000000040500002900000005040000290000001f025000390000000503200270000000200050008c000000000300401900000001020000290000001f022000390000000502200270000000000221001900000000013100190000000203000029000000000021004b00001a890000813d000000000001041b000000010110003900001a840000013d0000001f0050008c00001a9e0000a13d000000000040043f000000200200003900000000010000192470220f0000040f000000200700003900000003060000290000000405000029000000200200008a000000000225016f0000000003000019000000000023004b000000000467001900001aa20000813d0000000004040433000000000041041b00000020033000390000002007700039000000010110003900001a950000013d000000000005004b00001ab00000613d000000000103043300001ab10000013d000000000052004b00001aac0000813d0000000302500210000000f80220018f000000010300008a000000000223022f000000000232013f0000000003040433000000000223016f000000000021041b000000010150021000000001011001bf000000050400002900001ab80000013d00000000010000190000000302500210000000010300008a000000000223022f000000000232013f000000000121016f0000000102500210000000000121019f000000000014041b000000000001042d000009a501000041000000000010043f000000410100003900001ac10000013d000009a501000041000000000010043f0000002201000039000000040010043f000009a6010000410000247200010430000000400100043d000009dd0010009c00001ad10000813d0000008002100039000000400020043f0000006002000039000000000221043600000060031000390000000000030435000000400310003900000000000304350000000000020435000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a60100004100002472000104300000013702000039000000000202041a000000000012004b00001adc0000a13d0000237e0000013d000009c201000041000000000010043f000009710100004100002472000104300000013702000039000000000202041a000000000012004b00001ae50000a13d0000237e0000013d000009b901000041000000000010043f00000971010000410000247200010430000000000001004b00001aec0000613d000000000001042d000000400100043d0000006402100039000009de0300004100000000003204350000004402100039000009df03000041000000000032043500000024021000390000002b030000390000000000320435000009750200004100000000002104350000000402100039000000200300003900000000003204350000008402000039247021fd0000040f00070000000000020000013706000039000000000406041a000000010540003a00001b500000613d000500000001001d000600000003001d000000000056041b000000400100043d000009d20010009c00001b540000813d0000000003010019000300000001001d0000004001100039000000400010043f000200000002001d0000095b012001970000002002300039000400000002001d00000000001204350000000000030435000000000040043f0000013801000039000000200010043f00000040020000390000000001000019000700000004001d2470220f0000040f000000030200002900000000020204330000095b02200197000000040300002900000000030304330000008003300210000000000223019f000000000021041b0000000701000029000000000010043f000001390100003900011b260000003d0000232d0000013d000000050200002924701a5e0000040f00000006070000290000095a0170019800001b3c0000613d000500000001001d0000000001070019247021780000040f000000000001004b00001b5b0000613d0000000701000029000000000010043f000000cc01000039000000200010043f000000400200003900000000010000192470220f0000040f000000000201041a0000097a0220019700000005022001af000000000021041b0000000607000029000000400100043d0000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000800d020000390000000403000039000009e004000041000000070500002900000002060000292470223c0000040f000000010020019000001b5a0000613d0000000701000029000000000001042d000009a501000041000000000010043f000000110100003900001b570000013d000009a501000041000000000010043f0000004101000039000000040010043f000009a6010000410000247200010430000023320000013d000009b201000041000000000010043f000009710100004100002472000104300000000076010434000009d10060009c00001bed0000813d0000013505000039000000000305041a000000010430019000000001033002700000007f0330618f0000001f0030008c00000000080000390000000108002039000000000084004b00001bf10000c13d000000200030008c00001b7c0000413d000000000050043f0000001f046000390000000504400270000009e10440009a000000200060008c000009c6040040410000001f033000390000000503300270000009e10330009a000000000034004b00001b7c0000813d000000000004041b000000010440003900001b770000013d0000001f0060008c000000010300008a000000200400008a00001b8e0000a13d000000000050043f000000000846016f0000002009000039000009c607000041000000000a00001900000000008a004b000000000b19001900001b920000813d000000000b0b04330000000000b7041b000000200aa000390000002009900039000000010770003900001b850000013d000000000006004b00001b9e0000613d000000000107043300001b9f0000013d000000000068004b00001b9b0000813d0000000301600210000000f80110018f000000000113022f000000000131013f00000000080b0433000000000118016f000000000017041b000000010160021000000001011001bf00001ba50000013d00000000010000190000000307600210000000000773022f000000000737013f000000000171016f0000000106600210000000000161019f000000000015041b0000000065020434000009620050009c00001bed0000213d0000013601000039000000000801041a000000010080019000000001078002700000007f0770618f0000001f0070008c00000000090000390000000109002039000000000898013f000000010080019000001bf10000c13d000000200070008c00001bc40000413d000000000010043f0000001f085000390000000508800270000009e20880009a000000200050008c0000099f080040410000001f077000390000000507700270000009e20770009a000000000078004b00001bc40000813d000000000008041b000000010880003900001bbf0000013d000000200050008c00001bd40000413d0000002006000039000000000010043f000000000745016f0000099f040000410000000008000019000000000078004b000000000926001900001bd80000813d0000000009090433000000000094041b00000020088000390000002006600039000000010440003900001bcb0000013d000000000005004b00001be40000613d000000000206043300001be50000013d000000000057004b00001be10000813d0000000302500210000000f80220018f000000000223022f000000000232013f0000000003090433000000000223016f000000000024041b000000010250021000000001022001bf00001beb0000013d00000000020000190000000304500210000000000443022f000000000334013f000000000232016f0000000103500210000000000232019f000000000021041b000000000001042d000009a501000041000000000010043f000000410100003900001bf40000013d000009a501000041000000000010043f0000002201000039000000040010043f000009a60100004100002472000104300002000000000002000200000001001d24701ac40000040f0000000201000029000000000010043f000001380100003900011bff0000003d0000228b0000013d0000000002010019000000400100043d000009dd0010009c00001c160000813d000000000302041a0000008002100039000000400020043f000009e30010009c00001c160000213d000000a004100039000000400040043f00000000000204350000006004100039000000020500002900000000005404350000095b04300197000000400510003900000000004504350000008003300270000000200410003900000000003404350000000000210435000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a60100004100002472000104300000095a01100197000000000010043f0000010401000039000024030000013d0000095a02200197000000000020043f000024030000013d00020000000000020002095a0010019c00001c2f0000613d000000000020043f0000010301000039000000200010043f00011c2b0000003d000023930000013d000000000020043f00011c2e0000003d000022850000013d000000000001042d000009e401000041000000000010043f000009710100004100002472000104300002000000000002000200000002001d0000095a01100197000000000010043f0000010401000039000000200010043f00011c3b0000003d000023930000013d0000095a02200197000000000020043f00011c3f0000003d000022850000013d000000ff0110018f000000000001042d00000000060100190000006001100039000000a00700003900000000007104350000095a01300197000000400360003900000000001304350000095a0120019700000000011604360000000000010435000000a0016000390000000002040433000000000021043500000000030000190000002001100039000000000023004b00001c570000813d000000200440003900000000070404330000000000710435000000010330003900001c4f0000013d0000000002610049000000800360003900000000002304350000000002050433000000000021043500000000030000190000002001100039000000000023004b00001c650000813d000000200550003900000000040504330000000000410435000000010330003900001c5d0000013d000000000001042d0011000000000002000200000005001d0003095a0030019b0004095a0020019b0005095a0010019b000900200040003d000e00000004001d0000000001040433000a00000001001d00000000020000190000000a0020006c00001ce10000813d0000000e010000290000000001010433000000000021004b00001d750000a13d000d00000002001d00000005012002100000000901100029000c00000001001d0000000001010433247019280000040f000000000001004b00001cde0000613d0000000004010019000000400300043d0000096401000041000000000013043500000004013000390000096d0200004100000000002104350000000001000414000000040040008c000b00000004001d00001c910000613d00011c8b0000003d0000238b0000013d000800000003001d247016340000040f00000008030000290000000b04000029000000000001004b00001d7f0000613d00011c930000003d000022990000013d000009620050009c00001d790000213d000000010010019000001d790000c13d000000400050043f000009630070009c00001d740000213d0000001f0070008c00001d740000a13d000000000103043300011c9f0000003d000022520000013d00001d740000c13d000000000001004b00001cde0000613d000600000006001d000800000005001d000700000007001d0000000e0100002900000000010104330000000d0010006c00001d750000a13d0000000c010000290000000001010433000c00000001001d001100000004001d0000000004000415000000110440008a0000000504400210000080020100003900000960020000410000002403000039247022230000040f0000000b04000029000000000001004b00000007050000290000000803000029000000060600002900001d740000613d00000064013000390000000c0200002900000000002104350000004401300039000000030200002900000000002104350000002401300039000000040200002900000000002104350000096e0100004100000000001304350000000401300039000000050200002900000000002104350000000001000414000000040040008c00001cd30000613d000000000204001900011cce0000003d0000230e0000013d00001d8c0000613d0000001f01500039000000200200008a000000000621016f00000008030000290000000001360019000000000061004b00000000020000390000000102004039000009620010009c00001d790000213d000000010020019000001d790000c13d000000400010043f000009630050009c00001d740000213d0000000d02000029000000010220003900001c700000013d000000d001000039000000000101041a0000095a031001970000000a01000029000000010010008c000d00000003001d00001d160000c13d0000000e010000290000000001010433000000000001004b00001d750000613d00000002010000290000000012010434000000000002004b00001d750000613d00000009020000290000000002020433000e00000002001d0000000001010433000c00000001001d000f00000003001d00011cf80000003d000022780000013d0000000f0440008a00000005044002100000096002000041247022230000040f000000000001004b00001d740000613d000000400500043d00000084015000390000000c02000029000000000021043500000064015000390000000e0200002900000000002104350000004401500039000000030200002900000000002104350000002401500039000000040200002900000000002104350000096b01000041000000000015043500000004015000390000000502000029000000000021043500000000010004140000000d02000029000000040020008c00001d5f0000c13d000000010200003100001d660000013d001000000003001d00011d190000003d000022780000013d000000100440008a00000005044002100000096002000041247022230000040f000000000001004b00001d740000613d0000000d06000029000000400800043d0000006401800039000000a00200003900000000002104350000004401800039000000030200002900000000002104350000002401800039000000040200002900000000002104350000096a010000410000000000180435000000040180003900000005020000290000000000210435000000a4078000390000000e030000290000000003030433000000000037043500000000040000190000002007700039000000000034004b00001d3e0000813d0000000e050000290000002005500039000e00000005001d00000000050504330000000000570435000000010440003900001d340000013d00000000011700490000008403800039000000000013043500000002050000290000000001050433000000000017043500000000030000190000002007700039000000000013004b00001d4d0000813d000000200550003900000000040504330000000000470435000000010330003900001d450000013d0000000001000414000000040060008c00001d520000c13d000000010200003100001d5b0000013d000000000206001900000000048700490000000003080019000e00000008001d000000000508001900011d590000003d000023190000013d00001d9a0000613d0000000e0800002900011d5d0000003d000023eb0000013d000000000183001900001d6a0000013d000000a4040000390000000003050019000e00000005001d00011d640000003d000023190000013d00001da40000613d0000000e050000290000001f01200039000000200300008a000000000331016f000000000153001900011d6c0000003d000023e70000013d000009620010009c00001d790000213d000000010030019000001d790000c13d000000400010043f000009630020009c00001d740000213d000000000001042d000023320000013d000009a501000041000000000010043f000000320100003900001d7c0000013d000009a501000041000000000010043f0000004101000039000000040010043f000009a60100004100002472000104300000000304000367000000010200003100011d830000003d000022460000013d00001d890000613d000000000704034f000000000801001900011d880000003d000023150000013d00001d860000c13d000000000006004b00001d990000613d0000226c0000013d00011d8e0000003d000022ca0000013d00001d950000613d000000000603034f0000000007010019000000006806043c0000000007870436000000000097004b00001d910000c13d000000000005004b00001d990000613d00011d990000003d000022570000013d247021fd0000040f000000030400036700011d9d0000003d000022460000013d00001d890000613d000000000704034f000000000801001900011da20000003d000023150000013d00001da00000c13d00001d890000013d000000030400036700011da70000003d000022460000013d00001d890000613d000000000704034f000000000801001900011dac0000003d000023150000013d00001daa0000c13d00001d890000013d0016000000000002000300000003001d000500000001001d0000095a0110019800001f3b0000613d000700000002001d000900000001001d0000006501000039000000000101041a0000095a011001970000000002000411000600000002001d000000000012004b00001dbf0000c13d00011dbe0000003d000023510000013d0006006000100278000000400100043d001100000001001d000009d20010009c00001f190000813d00000011020000290000004001200039000000400010043f000000010300003900000000023204360000000701000029000d00000002001d0000000000120435000000400100043d000400000001001d000009660010009c00001f190000213d00000004020000290000004001200039000000400010043f0000000001320436000200000001001d00000000003104350000000701000029000000000010043f000001030100003900011dda0000003d0000228b0000013d0000000902000029000000000020043f00011dde0000003d000023340000013d000000010220003a00001f3d0000613d000000000021041b000000400100043d000000200210003900000001030000390000000000320435000000070200002900000000002104350000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f00000967011001c70000800d02000039000000040300003900000968040000410000000605000029000000000600001900000005070000292470223c0000040f000000010020019000001f140000613d00000006010000290008095a0010019b00000011010000290000000001010433000e00000001001d00000000020000190000000e0020006c00001e6c0000813d00000011010000290000000001010433000000000021004b00001f150000a13d001200000002001d00000005012002100000000d01100029001000000001001d0000000001010433247019280000040f000000000001004b00001e690000613d0000000004010019000000400300043d0000096401000041000000000013043500000004013000390000096d0200004100000000002104350000000001000414000000040040008c000f00000004001d00001e200000613d00011e1a0000003d0000238b0000013d000c00000003001d247016340000040f0000000c030000290000000f04000029000000000001004b00001f200000613d00011e220000003d000022990000013d000009620050009c00001f190000213d000000010010019000001f190000c13d000000400050043f000009630070009c00001f140000213d000000200070008c00001f140000413d000000000103043300011e2e0000003d000022520000013d00001f140000c13d000000000001004b00001e690000613d000a00000006001d000c00000005001d000b00000007001d00000011010000290000000001010433000000120010006c00001f150000a13d00000010010000290000000001010433001000000001001d001500000004001d0000000004000415000000150440008a0000000504400210000080020100003900000960020000410000002403000039247022230000040f000000000001004b00001f1f0000613d0000000c030000290000006401300039000000100200002900000000002104350000004401300039000000090200002900000000002104350000096e0100004100000000001304350000000401300039000000080200002900000000002104350000002401300039000000000001043500000000010004140000000f02000029000000040020008c0000000b050000290000000a0400002900001e600000613d00011e5b0000003d0000230e0000013d00001f2d0000613d0000001f01500039000000200200008a000000000421016f0000000c0300002900011e620000003d0000241d0000013d000009620010009c00001f190000213d000000010020019000001f190000c13d000000400010043f000009630050009c00001f140000213d0000001202000029000000010220003900001dff0000013d000000d001000039000000000101041a0000095a021001970000000e01000029000000010010008c001200000002001d00001ea10000c13d00000011010000290000000001010433000000000001004b00001f150000613d00000004010000290000000001010433000000000001004b00001f150000613d0000000d010000290000000001010433001100000001001d00000002010000290000000001010433001000000001001d001300000002001d00011e840000003d000022780000013d000000130440008a00000005044002100000096002000041247022230000040f000000000001004b00001f1f0000613d000000400500043d0000008401500039000000100200002900000000002104350000006401500039000000110200002900000000002104350000004401500039000000090200002900000000002104350000096b0100004100000000001504350000000401500039000000080200002900000000002104350000002401500039000000000001043500000000010004140000001202000029000000040020008c00001eca0000c13d000000010200003100001ed10000013d00011ea30000003d000024290000013d0000096002000041247022230000040f000000000001004b00001f1f0000613d000000400200043d0000096a010000410000000000120435001000000002001d0000000401200039000000060200002900000005030000290000001104000029000000040500002924701c410000040f000000000301001900000000010004140000001202000029000000040020008c00001ebc0000613d00000010050000290000000004530049000000000305001900011ebb0000003d000022bb0000013d00001f200000613d00011ebe0000003d0000246b0000013d0000001003200029000000000023004b00000000020000390000000102004039000009620030009c00001f190000213d000000010020019000001f190000c13d000000400030043f000009630010009c00001eda0000a13d00001f140000013d000000a4040000390000000003050019001200000005001d00011ecf0000003d000023190000013d00001f570000613d000000120500002900011ed30000003d000023b30000013d000009620030009c00001f190000213d000000010010019000001f190000c13d000000400030043f000009630020009c00001f140000213d001200000003001d001600050000002d000080020100003900000024030000390000000004000415000000160440008a00000005044002100000096002000041247022230000040f000000000001004b00001f130000613d000000120300002900011ee80000003d000023f60000013d00000001020000390000000000210435000000440130003900000007020000290000000000210435000009760100004100000000001304350000000401300039000000080200002900011ef30000003d000023ab0000013d00000000010004140000000902000029000000040020008c00001efe0000613d0000001205000029000000000453004900000020060000390000000003050019247016100000040f000000000001004b00001f430000613d00011f000000003d000022b60000013d0000001204000029000000000243001900011f040000003d000022900000013d000009620020009c00001f190000213d000000010030019000001f190000c13d000000400020043f000009630010009c00001f140000213d000000200010008c00001f140000413d0000000001040433000009770010019800001f140000c13d0000097801100197000009760010009c00001f410000c13d000000000001042d000023320000013d000009a501000041000000000010043f000000320100003900001f1c0000013d000009a501000041000000000010043f0000004101000039000000040010043f000009a6010000410000247200010430000023900000013d0000000304000367000000010200003100011f240000003d000022460000013d00001f2a0000613d000000000704034f000000000801001900011f290000003d000023150000013d00001f270000c13d000000000006004b00001f3a0000613d0000226c0000013d00011f2f0000003d000022ca0000013d00001f360000613d000000000603034f0000000007010019000000006806043c0000000007870436000000000097004b00001f320000c13d000000000005004b00001f3a0000613d00011f3a0000003d000022570000013d247021fd0000040f000009c00100004100001f540000013d000009a501000041000000000010043f000000110100003900001f1c0000013d000009bf0100004100001f540000013d0000000101000031000000040010008c00001f530000413d000000000100043d00000977011001970000000302000367000000000202043b0000097802200197000000000112019f000000000010043f0000097801100197000009750010009c00001f530000c13d2470212f0000040f000000000001004b00001f610000c13d000009be01000041000000000010043f00000971010000410000247200010430000000030400036700011f5a0000003d000022460000013d00001f2a0000613d000000000704034f000000000801001900011f5f0000003d000023150000013d00001f5d0000c13d00001f2a0000013d0000000002010019000000400300043d001200000003001d000009750100004100000000001304350000000401300039247016e20000040f000000120210006a0000001201000029247021fd0000040f0017000000000002000300000004001d000600000001001d0000095a01100198000020ff0000613d000800000002001d000a00000001001d0000006501000039000000000101041a0000095a011001970000000002000411000700000002001d000000000012004b00001f7c0000c13d00011f7b0000003d000023510000013d0007006000100278000000400100043d001200000001001d000009d20010009c000020dd0000813d00000012020000290000004001200039000000400010043f000000010100003900000000041204360000000802000029000e00000004001d0000000000240435000000400200043d000500000002001d000009660020009c000020dd0000213d00000005040000290000004002400039000000400020043f0000000001140436000200000001001d00000000003104350000000801000029000000000010043f0000010301000039000000200010043f00000040020000390000000001000019000400000003001d2470220f0000040f0000000a02000029000000000020043f00011f9e0000003d0000232d0000013d0000000404000029000000010200008a000000000324013f000000000201041a000000000032004b000021010000213d0000000002420019000000000021041b000000400100043d00000020021000390000000000420435000000080200002900000000002104350000091d0010009c0000091d01008041000000400110021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f00000967011001c70000800d02000039000000040300003900000968040000410000000705000029000000000600001900000006070000292470223c0000040f0000000100200190000020d80000613d00000007010000290009095a0010019b00000012010000290000000001010433000f00000001001d00000000020000190000000f0020006c000020300000813d00000012010000290000000001010433000000000021004b000020d90000a13d001300000002001d00000005012002100000000e01100029001100000001001d0000000001010433247019280000040f000000000001004b0000202d0000613d0000000004010019000000400300043d0000096401000041000000000013043500000004013000390000096d0200004100000000002104350000000001000414000000040040008c001000000004001d00001fe40000613d00011fde0000003d0000238b0000013d000d00000003001d247016340000040f0000000d030000290000001004000029000000000001004b000020e40000613d00011fe60000003d000022990000013d000009620050009c000020dd0000213d0000000100100190000020dd0000c13d000000400050043f000009630070009c000020d80000213d000000200070008c000020d80000413d000000000103043300011ff20000003d000022520000013d000020d80000c13d000000000001004b0000202d0000613d000b00000006001d000d00000005001d000c00000007001d00000012010000290000000001010433000000130010006c000020d90000a13d00000011010000290000000001010433001100000001001d001600000004001d0000000004000415000000160440008a0000000504400210000080020100003900000960020000410000002403000039247022230000040f000000000001004b000020e30000613d0000000d0300002900000064013000390000001102000029000000000021043500000044013000390000000a0200002900000000002104350000096e0100004100000000001304350000000401300039000000090200002900000000002104350000002401300039000000000001043500000000010004140000001002000029000000040020008c0000000c050000290000000b04000029000020240000613d0001201f0000003d0000230e0000013d000020f10000613d0000001f01500039000000200200008a000000000421016f0000000d03000029000120260000003d0000241d0000013d000009620010009c000020dd0000213d0000000100200190000020dd0000c13d000000400010043f000009630050009c000020d80000213d0000001302000029000000010220003900001fc30000013d000000d001000039000000000101041a0000095a021001970000000f01000029000000010010008c001300000002001d000020620000c13d00000012010000290000000001010433000000000001004b000020d90000613d00000005010000290000000001010433000000000001004b000020d90000613d0000000e010000290000000001010433001200000001001d00000002010000290000000001010433001100000001001d000120470000003d000024290000013d0000096002000041247022230000040f000000000001004b000020e30000613d000000400500043d00000084015000390000001102000029000000000021043500000064015000390000001202000029000000000021043500000044015000390000000a0200002900000000002104350000096b0100004100000000001504350000000401500039000000090200002900000000002104350000002401500039000000000001043500000000010004140000001302000029000000040020008c0000208e0000c13d0000000102000031000020950000013d001500000002001d000120650000003d000022780000013d000000150440008a00000005044002100000096002000041247022230000040f000000000001004b000020e30000613d000000400200043d0000096a010000410000000000120435001100000002001d0000000401200039000000070200002900000006030000290000001204000029000000050500002924701c410000040f000000000301001900000000010004140000001302000029000000040020008c000020800000613d0000001105000029000000000453004900000000030500190001207f0000003d000022bb0000013d000020e40000613d000120820000003d0000246b0000013d0000001103200029000000000023004b00000000020000390000000102004039000009620030009c000020dd0000213d0000000100200190000020dd0000c13d000000400030043f000009630010009c0000209e0000a13d000020d80000013d000000a4040000390000000003050019001300000005001d000120930000003d000023190000013d0000211b0000613d0000001305000029000120970000003d000023b30000013d000009620030009c000020dd0000213d0000000100100190000020dd0000c13d000000400030043f000009630020009c000020d80000213d001300000003001d001700060000002d000080020100003900000024030000390000000004000415000000170440008a00000005044002100000096002000041247022230000040f000000000001004b000020d70000613d0000001303000029000120ac0000003d000023f60000013d000000040200002900000000002104350000004401300039000000080200002900000000002104350000097601000041000000000013043500000004013000390000000902000029000120b70000003d000023ab0000013d00000000010004140000000a02000029000000040020008c000020c20000613d0000001305000029000000000453004900000020060000390000000003050019247016100000040f000000000001004b000021070000613d000120c40000003d000022b60000013d00000013040000290000000002430019000120c80000003d000022900000013d000009620020009c000020dd0000213d0000000100300190000020dd0000c13d000000400020043f000009630010009c000020d80000213d000000200010008c000020d80000413d00000000010404330000097700100198000020d80000c13d0000097801100197000009760010009c000021050000c13d000000000001042d000023320000013d000009a501000041000000000010043f0000003201000039000020e00000013d000009a501000041000000000010043f0000004101000039000000040010043f000009a6010000410000247200010430000023900000013d00000003040003670000000102000031000120e80000003d000022460000013d000020ee0000613d000000000704034f0000000008010019000120ed0000003d000023150000013d000020eb0000c13d000000000006004b000020fe0000613d0000226c0000013d000120f30000003d000022ca0000013d000020fa0000613d000000000603034f0000000007010019000000006806043c0000000007870436000000000097004b000020f60000c13d000000000005004b000020fe0000613d000120fe0000003d000022570000013d247021fd0000040f000009c001000041000021180000013d000009a501000041000000000010043f0000001101000039000020e00000013d000009bf01000041000021180000013d0000000101000031000000040010008c000021170000413d000000000100043d00000977011001970000000302000367000000000202043b0000097802200197000000000112019f000000000010043f0000097801100197000009750010009c000021170000c13d2470212f0000040f000000000001004b000021250000c13d000009be01000041000000000010043f0000097101000041000024720001043000000003040003670001211e0000003d000022460000013d000020ee0000613d000000000704034f0000000008010019000121230000003d000023150000013d000021210000c13d000020ee0000013d0000000002010019000000400300043d001300000003001d000009750100004100000000001304350000000401300039247016e20000040f000000130210006a0000001301000029247021fd0000040f00010000000000020000000105000031000000430050008c0000000001000019000021350000213d000000000001042d00000004010000390000000306100367000000040450008a000000200200008a00000000072401700000001f0840018f000000400300043d0000000001730019000021440000613d000000000906034f000000000a030019000000009b09043c000000000aba043600000000001a004b000021400000c13d000000000008004b000021510000613d000000000676034f0000000307800210000000000801043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f00000000006104350000000006030433000009620060009c000021700000213d0000002401600039000000000051004b0000000001000019000021340000213d00000000053600190000000007050433000009620070009c0000000001000019000021340000213d000000000134001900000000047500190000002004400039000000000014004b0000000001000019000021340000213d00000000017600190000003f01100039000000000221016f0000000001320019000121690000003d000023fb0000013d000009620010009c000021720000213d0000000100200190000021720000c13d000000400010043f0000000001050019000000000001042d0000000001000019000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a60100004100002472000104300002000000000002000200000001001d247021ab0000040f000000000001004b000021a20000613d0000000201000029247021d30000040f000000000001004b0000000002000019000021a30000c13d0000000205000029000000400100043d0000002003100039000009640200004100000000002304350000002402100039000009e504000041000000000042043500000024020000390000000000210435000009e60010009c000021a50000813d0000006002100039000000400020043f000000040050008c000021950000c13d0000000001030433000000000010043f0000219a0000013d0000000002050019000121980000003d000023260000013d000021a20000613d000000000100043d0000000102000031000000200020008c0000000002000019000021a30000413d000000000001004b0000000002000039000000010200c039000021a30000013d0000000002000019000000010120018f000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a601000041000024720001043000010000000000020000000002010019000000400100043d0000002003100039000009640400004100000000004304350000002405100039000000000045043500000024040000390000000000410435000009e60010009c000021cd0000813d0000006004100039000000400040043f000000040020008c000021be0000c13d0000000001030433000000000010043f000021c20000013d000121c00000003d000023260000013d000021ca0000613d000000000100043d0000000102000031000000200020008c0000000002000019000021cb0000413d000000000001004b0000000002000039000000010200c039000021cb0000013d0000000002000019000000010120018f000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a601000041000024720001043000010000000000020000000002010019000000400100043d00000020031000390000096404000041000000000043043500000024041000390000097805000041000000000054043500000024040000390000000000410435000009e60010009c000021f60000813d0000006004100039000000400040043f000000040020008c000021e70000c13d0000000001030433000000000010043f000021eb0000013d000121e90000003d000023260000013d000021f30000613d000000000100043d0000000102000031000000200020008c0000000002000019000021f40000413d000000000001004b0000000002000039000000010200c039000021f40000013d0000000002000019000000010120018f000000000001042d000009a501000041000000000010043f0000004101000039000000040010043f000009a6010000410000247200010430000000000001042f0000091d0010009c0000091d0100804100000040011002100000091d0020009c0000091d020080410000006002200210000000000112019f00002472000104300000091d0010009c0000091d0100804100000040011002100000091d0020009c0000091d020080410000006002200210000000000112019f000000e002300210000000000121019f000024710001042e0000091d0010009c0000091d0100804100000040011002100000091d0020009c0000091d020080410000006002200210000000000112019f00000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f0000097b011001c70000801002000039247022410000040f0000000100200190000022220000613d000000000101043b000000000001042d000023320000013d00000000050100190000000000200443000000040100003900000005024002700000000002020031000000000121043a0000002004400039000000000031004b000022260000413d0000091d0030009c0000091d03008041000000600130021000000000020004140000091d0020009c0000091d02008041000000c002200210000000000112019f000009e7011001c70000000002050019247022410000040f00000001002001900000223b0000613d000000000101043b000000000001042d000000000001042f0000223f002104210000000102000039000000000001042d0000000002000019000000000001042d00002244002104230000000102000039000000000001042d0000000002000019000000000001042d000000200100008a00000000051201700000001f0620018f000000400100043d0000000003510019000000010000013b000000140100008a00000000011000310000000201100367000000000101043b0000006001100270000000010000013b000000000001004b0000000002000039000000010200c039000000000021004b000000010000013b000000000343034f0000000304500210000000000509043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000390435000000010000013b00000001010000310000001f02100039000000200300008a000000000332016f0000001502300029000000000032004b00000000030000390000000103004039000000010000013b000000000454034f0000000305600210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435247021fd0000040f000080020100003900000024030000390000000004000415000000010000013b000000000010043f000000ca01000039000000200010043f000000400200003900000000010000192470220f0000040f000000000101041a000000000001004b000000010000013b000000200010043f000000000100001900000040020000392470220f0000040f000000000101041a000000010000013b000000200010043f000000400200003900000000010000192470220f0000040f000000010000013b000000000032004b00000000030000390000000103004039000000010000013b00000000050300190000000006000019247016100000040f000000000001004b000000010000013b00000001070000310000001f01700039000000200200008a000000000621016f0000000005360019000000000065004b00000000010000390000000101004039000000010000013b00000000010b0019247017ee0000040f001300000001001d001200000002001d001100000003001d001400000004001d000f00000005001d001500000006001d0000000001000415001000000001001d247018280000040f247018d60000040f00000013010000290000001202000029000000110300002924701afd0000040f001300000001001d00000014010000290000000021010434000000010000013b00000001010000310000001f02100039000000200300008a000000000332016f000000010000013b0000000006000019247016100000040f000000000001004b000000010000013b0000013401000039000000000201041a000000010020019000000001012002700000007f0110618f0000001f0010008c00000000030000390000000103002039000000000232013f0000000100200190000000010000013b0000000303000367000000200100008a000000000415017000000000020500190000001f0550018f000000400100043d0000000009410019000000010000013b000000000010043f0000013801000039000000200010043f000000400200003900000000010000192470220f0000040f000000000201041a000000010000013b000000000020043f0000013801000039000000200010043f000000400200003900000000010000192470220f0000040f000000400200043d000000010000013b00000015020000290000004001200039000000400010043f0000000001020436000d00000001001d0000000000010435000000000100041a0000000801100270000000ff0110018f000c00000001001d24701ae90000040f0000000d0100002900000000010104330000ffff0110018f000027100010008c000000010000013b247018460000040f000000000100041a0000000801100270000000ff0110018f000c00000001001d24701ae90000040f0000000c0100002924701ae90000040f00000097010000390000000102000039000000000021041b0000001201000029247018460000040f00000015010000290000000001010433000000010000013b00000097010000390000000102000039000000000021041b0000000001000415000000010000013b0000004003200039000000400030043f000000000301041a000000200420003900000080013002700000000000140435000000010000013b000000840400003900000000050300190000000006000019247016100000040f0000000105000031000000000001004b000000010000013b000000007907043c0000000008980436000000000038004b000000010000013b0000000006000019247016100000040f0000000102000031000000000001004b000000010000013b0000000302400210000000010300008a000000000223022f000000000232013f000000000121016f0000000102400210000000000121019f000000010000013b0000000004010433000075300100003900000020060000390000000005000019247016340000040f000000000001004b000000010000013b000000200010043f000000000100001900000040020000392470220f0000040f000000010000013b00000000010000190000247200010430000000200010043f000000000100001900000040020000392470220f0000040f000000000201041a000000010000013b000000000661034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f0000000000540435000000010000013b0000001301000029000000000010043f000000ce01000039000000200010043f001200000002001d000000400200003900000000010000192470220f0000040f00000014020000290000000002020433000000010000013b000000140100008a00000000011000310000000201100367000000000101043b000000010000013b00000015020000290000000302200210000000f80220018f000000010300008a000000000223022f000000000232013f0000000003050433000000000223016f000000000021041b000000010000013b00000001010000310000001f02100039000000200300008a000000000232016f0000000003520019000000000023004b00000000020000390000000102004039001400000003001d000000010000013b000000000704043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f0000000000540435000000010000013b0000000801000029000000100200002924701b5f0000040f000000000100041a0000000801100270000000ff0110018f24701ae90000040f0000006502000039000000000102041a000000010000013b000000000010043f0000013901000039000000200010043f000000400200003900000000010000192470220f0000040f247016900000040f000000000001042d000000000021043500000024013000390000000c020000290000000000210435000000010000013b0000000002040019000000240400003900000000050300190000002006000039000000010000013b00000000010000190000000002000019247021fd0000040f000000400200003900000000010000192470220f0000040f0000000202000029000000010000013b000000000403041a000000a005200039000000000045043500000020022000390000000103300039000000010000013b0000013701000039000000000101041a0000001402000029000000000021004b000000010000013b00000000001c0435000001a001c0003900000000000104350000018001c000390000000000010435000000a001c000390000000000010435000000010000013b000000000021043500000024013000390000000000010435000000a4023000390000000301000029247016ce0000040f0000000003010019000000010000013b0000001f01200039000000200300008a000000000131016f0000000003510019000000000013004b00000000010000390000000101004039000000010000013b000000000101043b000000000010043f000000ce01000039000000200010043f000000000100001900000040020000392470220f0000040f000000010000013b000000400050043f00000014050000290000000003350436001300000003001d000000000242001900000040022000390000000a0020006c000000010000013b00000014011000290000000a02000029247019370000040f001000000001001d0000000f010000290000000001010433000f00000001001d000000010000013b000000000302041a000000010430019000000001013002700000007f0110618f0000001f0010008c00000000050000390000000105002039000000010000013b00000014021000290000001401400029000a00000002001d247019370000040f000900000001001d00000013010000290000000001010433000000010000013b000100000003001f00030000000103550000000001020019000000000001042d000000000031004b00000000030000390000000103004039000000010000013b0000001f01200039000000200300008a000000000331016f000000010000013b0000000f011001af000000000012041b00000014010000290000000001010433001200000001001d0000000002000019000000010000013b0000008401300039000000a00200003900000000002104350000006401300039000000010000013b000000000021004b00000000020000390000000102004039000000010000013b247018d60000040f0000006501000039000000000101041a000000010000013b000000200010043f000000400200003900000000010000192470220f0000040f000000000001042d000000000203043b001400000002001d000000040110003900000000020b00192470177d0000040f001300000001001d000000010000013b000000400600043d0000000005560019001400000006001d000000000065004b00000000060000390000000106004039000000010000013b000000000020043f000000200010043f000000000100001900000040020000392470220f0000040f000000010200008a000000010000013b0000000001340019000000000041004b00000000020000390000000102004039000000010000013b00000014011000290000000a02000029247019370000040f000800000001001d00000010010000290000000001010433000000010000013b001400000002001d000080020100003900000024030000390000000004000415000000140440008a0000000504400210000000010000013b00000137010000390000000102000039000000000021041b00000009010000290000000001010433001500000001001d000000010000013b000000000013043500000004013000390000000b020000290000000000210435000000010000013b0000000c0100002924701ae90000040f0000000c0100002924701ae90000040f0000006501000039000000000101041a000000010000013b0000001301000029000000000010043f0000010301000039000000200010043f000000400200003900000000010000192470220f0000040f0000001502000029000000000020043f000000010000013b0000000a01000029000000000010043f0000010301000039000000200010043f000000400200003900000000010000192470220f0000040f0000000c02000029000000000020043f000000010000013b00000001010000310000001f02100039000000200300008a000000000332016f0000001302300029000000010000013b00000001010000310000001f02100039000000200300008a000000000332016f0000000002530019000000010000013b00000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f000000010000013b00000001010000310000001f02100039000000200300008a000000000232016f000000010000013b0000247000000432000024710001042e0000247200010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff000000020000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000f97b57ec0000000000000000000000000000000000000000000000000000000001ffc9a700000000000000000000000000000000000000000000000000000000063a7502000000000000000000000000000000000000000000000000000000000690a78d0000000000000000000000000000000000000000000000000000000006fdde03000000000000000000000000000000000000000000000000000000000e89341c0000000000000000000000000000000000000000000000000000000017360d340000000000000000000000000000000000000000000000000000000018160ddd0000000000000000000000000000000000000000000000000000000018bae6c8000000000000000000000000000000000000000000000000000000001b30808d000000000000000000000000000000000000000000000000000000002a55205a000000000000000000000000000000000000000000000000000000002a5ac764000000000000000000000000000000000000000000000000000000002eb2c2d600000000000000000000000000000000000000000000000000000000336211bf000000000000000000000000000000000000000000000000000000003659cfe600000000000000000000000000000000000000000000000000000000377e5e270000000000000000000000000000000000000000000000000000000046134b500000000000000000000000000000000000000000000000000000000047230dcb000000000000000000000000000000000000000000000000000000004e1273f4000000000000000000000000000000000000000000000000000000004f1ef286000000000000000000000000000000000000000000000000000000004f58122a0000000000000000000000000000000000000000000000000000000050cf5a310000000000000000000000000000000000000000000000000000000052d1902d00000000000000000000000000000000000000000000000000000000572b6c05000000000000000000000000000000000000000000000000000000006502abea00000000000000000000000000000000000000000000000000000000662fff38000000000000000000000000000000000000000000000000000000006b15fd4500000000000000000000000000000000000000000000000000000000715018a60000000000000000000000000000000000000000000000000000000075794a3c00000000000000000000000000000000000000000000000000000000834a20df000000000000000000000000000000000000000000000000000000008da5cb5b0000000000000000000000000000000000000000000000000000000091d0049e00000000000000000000000000000000000000000000000000000000921727040000000000000000000000000000000000000000000000000000000095d89b4100000000000000000000000000000000000000000000000000000000a22cb46500000000000000000000000000000000000000000000000000000000a305f5b200000000000000000000000000000000000000000000000000000000b1b00d0e00000000000000000000000000000000000000000000000000000000b5c5801e00000000000000000000000000000000000000000000000000000000b859c93500000000000000000000000000000000000000000000000000000000bfb2995c00000000000000000000000000000000000000000000000000000000c2f5070100000000000000000000000000000000000000000000000000000000c87b56dd00000000000000000000000000000000000000000000000000000000cbab0bd300000000000000000000000000000000000000000000000000000000d1f5789400000000000000000000000000000000000000000000000000000000ddf990f900000000000000000000000000000000000000000000000000000000e8a3d48500000000000000000000000000000000000000000000000000000000e985e9c500000000000000000000000000000000000000000000000000000000eb87215000000000000000000000000000000000000000000000000000000000ee295d6200000000000000000000000000000000000000000000000000000000eeab058900000000000000000000000000000000000000000000000000000000ef60ceaf00000000000000000000000000000000000000000000000000000000f242432a00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000f5298aca00000000000000000000000000000000000000000000000000000000f775baac00000000000000000000000000000000000000000000000000000000f83e6ed80000000000000000000000000000000000000000000000000000000000fdd58e66be4f155c5ef2ebd3772b228f2f00681e4ed5826cdb3b1943cc11ad15ad1d28000000000000000000000000000000000000000000000000ffffffffffffff7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff3f0000000000000000000000000000000000000000ffffffffffffffffffffffff1806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83e28be14400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01ffc9a700000000000000000000000000000000000000000000000000000000129dae8b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffbf0200000000000000000000000000000000000040000000000000000000000000c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62000000000000000000000000000000000000000000000000ffffffffffffffdfbcee357900000000000000000000000000000000000000000000000000000000205b13af00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000f5e8d69e000000000000000000000000000000000000000000000000000000007f1eaf8500000000000000000000000000000000000000000000000000000000f4d678b800000000000000000000000000000000000000000000000000000000160fca8a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000eeddf6ab0000000000000000000000000000000000000000000000000000000064647265737300000000000000000000000000000000000000000000000000004f776e61626c653a206e6577206f776e657220697320746865207a65726f206108c379a000000000000000000000000000000000000000000000000000000000f23a6e610000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000049a5c0f000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c5ea6e4103e78cb101e796fb2dace540362fc542cbff5145eaa24af7dd8fe41d10072c000000000000000000000000000000000000000000000000000000000acc0f6922d8ccd133dbdaee1908d4d734f25a540223d55145e9fad2898471a4e15bd85bf0000000000000000000000000000000000000000000000000000000085e335b600000000000000000000000000000000000000000000000000000000e1c588fe1269da19c317f679b04e226f5e48296f9b2c8351127eb010907c472f000000000000000000000000000000000000000000000000ffffffffffffff41ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000080647920696e697469616c697a6564000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e747261637420697320616c72656180000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02caa1ae20000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000000000000000007f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024983a9654d81ac4dafbb9a2fb1cd3efa3de2783ae40b06b17a456bf5922ed02a3a7d018c0fa00000000000000000000000000000000000000000000000000000000e236d251e7da4ac8a3c275f80aebc9b74cbf356425fa04864da5043511a81219eabab42200000000000000000000000000000000000000000000000000000000ad6e40c7000000000000000000000000000000000000000000000000000000009c39c41c00000000000000000000000000000000000000000000000000000000eaf422d1ab2d8f38856ab6be8378c08d2886463a33667e896ba3a6ebf2c6260c57c31fde00000000000000000000000000000000000000000000000000000000f6bdd07c000000000000000000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000ce2003a500000000000000000000000000000000000000000000000000000000c407dfe559ca4a63d7cf8439b9fce2965d7a4c8c92eb5d5047f53bb9eec295fd16365cdd000000000000000000000000000000000000000000000000000000003c2d7b840f03bc7a1e02b5faf6a89bb740590f5871b876deae799c89188634d1a5af901600000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000080000000000000000017307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31ccea9e6f0000000000000000000000000000000000000000000000000000000039da2db355130acf428d669fbf1c14faa9d51399a25b793fc254bbbde66f02e2000000000000000000000000000000000000000000000000fffffffffffffe3f0000000000000000000000000000000000000000000000000000ffffffffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff77a856ea000000000000000000000000000000000000000000000000000000009941b0eaa3a10d142c88d4dd70d0ff97e1b12a7d9324c4e6bc33ee52ea52e2d94e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000073e05f4c0a27cbf60841afa4a2f8577f5e99db3e3e9c293800d6e6b1f7b8a7aba9292a6f000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e555550535570677261646561626c653a206d757374206e6f742062652063616c6c6564207468726f7567682064656c656761746563616c6c0000000000000000360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8808898a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff9fbcdbc94700000000000000000000000000000000000000000000000000000000e10a05050000000000000000000000000000000000000000000000000000000034e70f7a0000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d30c2588339a383e2c3092b5383924cf202ae9c377b76c5fe5208cd41d8d2aa80d93734000000000000000000000000000000000000000000000000000000004a3891c200000000000000000000000000000000000000000000000000000000bf317c2a00000000000000000000000000000000000000000000000000000000ea6eb5c300000000000000000000000000000000000000000000000000000000ceea21b60000000000000000000000000000000000000000000000000000000099b2a73600000000000000000000000000000000000000000000000000000000b4fa3fb3000000000000000000000000000000000000000000000000000000004a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fbbc197c8100000000000000000000000000000000000000000000000000000000fc3c12d200000000000000000000000000000000000000000000000000000000c6017f5f00000000000000000000000000000000000000000000000000000000ea553b34000000000000000000000000000000000000000000000000000000005bf57bc300000000000000000000000000000000000000000000000000000000eb4929030000000000000000000000000000000000000000000000000000000052df9fe50000000000000000000000000000000000000000000000000000000045a9661700000000000000000000000000000000000000000000000000000000f8d2906c00000000000000000000000000000000000000000000000000000000df37d27e88e3bd0b85262482997e409a463f5be0ebb19232abf994dd8474090d9d22e78e000000000000000000000000000000000000000000000000000000001b0445890000000000000000000000000000000000000000000000000000000082b429000000000000000000000000000000000000000000000000000000000074c1ace100000000000000000000000000000000000000000000000000000000ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9d4b38394dff663b46f53f52ced584161b5021180321b381f6104325eecebf49fd120bd2000000000000000000000000000000000000000000000000000000000e89341c00000000000000000000000000000000000000000000000000000000d9b67a260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffe00000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000ffffffffffffffc04f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657246756e6374696f6e206d7573742062652063616c6c6564207468726f756768206163746976652070726f787900000000000000000000000000000000000000004e6f74207570677261646561626c65000000000000000000000000000000000064656c656761746563616c6c00000000000000000000000000000000000000009941b0eaa3a10d142c88d4dd70d0ff97e1b12a7d9324c4e6bc33ee52ea52e2d808000000000000000000000000000000000000000000000000000000000000005265656e7472616e637947756172643a207265656e7472616e742063616c6c00ffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff1e3a7701ed9625e63ce809864fb1dd90a1b7d69064d37caeed814fef6f83b8d1000000000000000000000000000000000000000000000000ffffffffffffff806e697469616c697a696e67000000000000000000000000000000000000000000496e697469616c697a61626c653a20636f6e7472616374206973206e6f7420697fe7f72f14a53255f3c9e225ab1d40fdb21335b87a7912726a196fb816866ae020c82d81771c42f47ad9db7d6681bf65b9c0a41f144e6dcd54066b227b8bf6f3c625d24caaecf530bd72996040e3eb05562aec665da486c03dab44421990fd1e000000000000000000000000000000000000000000000000ffffffffffffff5f49e27cff0000000000000000000000000000000000000000000000000000000076413c5e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffa00200000200000000000000000000000000000000000000000000000000000000ed3f649d9fc5327d79c6f6c480b5e38bbdd235d8871beb5a895f06e28a8509ef
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.