ERC-721
Overview
Max Total Supply
0 YNFT
Holders
157
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 YNFTLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Yakyuken
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import { ERC721URIStorage } from "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import { Base64 } from "@openzeppelin/contracts/utils/Base64.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ERC721B } from "./ERC721B.sol"; import { ZLib } from "./zip/ZLib.sol"; contract Yakyuken is ERC721B, ERC721URIStorage, Ownable { using Strings for uint256; bytes32 private constant METADATA_POINTER = bytes32(keccak256("metadata")); uint16 private constant MEMORY_OFFSET = 100; address private immutable _zlib; uint128[] private _imageMetadata; uint128[] private _iconMetadata; bytes7[] private _imageTraits; bytes7 private _sampleImageTraits; bool[4] private _initialized; address private _saleContract; struct Image { string path; string viewBox; string fontSize; string iconSize; string name; } ///@dev must be in alphabetical order struct Icon { string color; string name; string path; } struct MetadataBytes { uint8 glowTimes; uint8 backgroundColors; uint8 yakHoverColors; uint8 finalShadowColors; uint8 baseFillColors; uint8 yakFillColors; uint8 yak; uint8 initialShadowColors; uint8 initialShadowBrightness; uint8 finalShadowBrightness; uint8 icon; uint8 texts; } ///@dev must be in alphabetical order struct Metadata { string[] backgroundColors; string[] baseFillColors; string[] finalShadowBrightness; string[] finalShadowColors; string[] glowTimes; string[] initialShadowBrightness; string[] initialShadowColors; string[] texts; string[] yakFillColors; string[] yakHoverColors; } error OutOfBondsTraitValueError(); error AlreadyInitializedError(); error NotSaleContractError(); modifier initialize(uint256 id_) { _initialize(id_); _; } modifier onlySale() { if (msg.sender != _saleContract) revert NotSaleContractError(); _; } constructor(address zlib_) ERC721("Yakyuken", "YNFT") Ownable(msg.sender) { _zlib = zlib_; for (uint256 i = 0; i < 25; i++) { _mint(msg.sender, i); } } ///@dev must be the first initialize to be called function initializeMetadata(bytes calldata metadata_, bytes7 sampleImageTraits_) external onlyOwner initialize(0) { _write(METADATA_POINTER, metadata_); _sampleImageTraits = sampleImageTraits_; } ///@dev must be called after initializeMetadata(). function initializeImages(bytes[] calldata images_, uint128[] calldata decompressedSizes_) external onlyOwner initialize(1) { uint256 imageCount_ = images_.length; for (uint256 i_; i_ < imageCount_; i_++) { _write(bytes32(keccak256(abi.encode(i_))), images_[i_]); _imageMetadata.push(decompressedSizes_[i_]); } } ///@dev must be called after initializeImages(). function initializeImagesHardcoded( bytes[] calldata images_, uint128[] calldata decompressedSizes_, uint256 totalImages_ ) external onlyOwner initialize(2) { uint256 imageCount_ = totalImages_ - images_.length; for (uint256 i_; i_ < images_.length; i_++) { _write(bytes32(keccak256(abi.encode(i_ + imageCount_))), images_[i_]); _imageMetadata.push(decompressedSizes_[i_]); } } ///@dev must be called after initializeImagesHardcoded() function initializeIcons(bytes[] calldata icons_, uint128[] calldata decompressedSizesIcons_) external onlyOwner initialize(3) { uint256 iconCount_ = icons_.length; for (uint256 j_; j_ < iconCount_; j_++) { _write(bytes32(keccak256(abi.encode(j_ + MEMORY_OFFSET))), icons_[j_]); _iconMetadata.push(decompressedSizesIcons_[j_]); } } function reveal(bytes7[] memory imageTraits_) external onlyOwner { _imageTraits = imageTraits_; } function tokenURI(uint256 tokenId_) public view override returns (string memory) { MetadataBytes memory data_; data_ = processMetadataAsBytes(_imageTraits.length > 0 ? _imageTraits[tokenId_] : _sampleImageTraits); Metadata memory metadata_ = abi.decode(_read(METADATA_POINTER), (Metadata)); Image memory image_ = abi.decode( ZLib(_zlib).inflate(_read(bytes32(keccak256(abi.encode(data_.yak)))), _imageMetadata[data_.yak]), (Image) ); Icon memory icon_ = abi.decode( ZLib(_zlib).inflate( _read(bytes32(keccak256(abi.encode(data_.icon + MEMORY_OFFSET)))), _iconMetadata[data_.icon] ), (Icon) ); bytes memory dataURI = abi.encodePacked( "{", '"name": "Yakyuken #', tokenId_.toString(), '", "description": "', "Yakyuken NFT on-chain collection.", '", "image_data": "', string( abi.encodePacked( "data:image/svg+xml;base64,", Base64.encode(_generateSVGfromBytes(data_, metadata_, image_, icon_)) ) ), '",', _getAttributes(data_, metadata_, [image_.name, icon_.name]), "}" ); return string(abi.encodePacked("data:application/json;base64,", Base64.encode(dataURI))); } function generateSVGfromBytes(uint256 tokenId_) external view returns (string memory svg_) { MetadataBytes memory data_; data_ = processMetadataAsBytes(_imageTraits.length > 0 ? _imageTraits[tokenId_] : _sampleImageTraits); Metadata memory metadata_ = abi.decode(_read(METADATA_POINTER), (Metadata)); Image memory image_ = abi.decode( ZLib(_zlib).inflate(_read(bytes32(keccak256(abi.encode(data_.yak)))), _imageMetadata[data_.yak]), (Image) ); Icon memory icon_ = abi.decode( ZLib(_zlib).inflate( _read(bytes32(keccak256(abi.encode(data_.icon + MEMORY_OFFSET)))), _iconMetadata[data_.icon] ), (Icon) ); svg_ = string(_generateSVGfromBytes(data_, metadata_, image_, icon_)); } function processMetadataAsBytes(bytes7 metadataInfo_) public view returns (MetadataBytes memory data_) { Metadata memory metadata_ = abi.decode(_read(METADATA_POINTER), (Metadata)); data_.glowTimes = _getTraitFromMask(metadataInfo_, 0, 0, metadata_.glowTimes.length); data_.backgroundColors = _getTraitFromMask(metadataInfo_, 1, 0, metadata_.backgroundColors.length); data_.yakHoverColors = _getTraitFromMask(metadataInfo_, 2, 4, metadata_.yakHoverColors.length); data_.finalShadowColors = _getTraitFromMask(metadataInfo_, 2, 10, metadata_.finalShadowColors.length); data_.baseFillColors = _getTraitFromMask(metadataInfo_, 3, 4, metadata_.baseFillColors.length); data_.yakFillColors = _getTraitFromMask(metadataInfo_, 3, 10, metadata_.yakFillColors.length); data_.yak = _getTraitFromMask(metadataInfo_, 4, 4, _imageMetadata.length); data_.initialShadowColors = _getTraitFromMask(metadataInfo_, 4, 10, metadata_.initialShadowColors.length); data_.initialShadowBrightness = _getTraitFromMask(metadataInfo_, 5, 4, metadata_.initialShadowBrightness.length); data_.finalShadowBrightness = _getTraitFromMask(metadataInfo_, 5, 10, metadata_.finalShadowBrightness.length); data_.icon = _getTraitFromMask(metadataInfo_, 6, 4, _iconMetadata.length); data_.texts = _getTraitFromMask(metadataInfo_, 6, 10, metadata_.texts.length); } function mint(address to_, uint256 tokenId_) external onlySale { _mint(to_, tokenId_); } function setSaleContract(address sale_) external onlyOwner { _saleContract = sale_; } function _initialize(uint256 id_) internal { if (_initialized[id_]) revert AlreadyInitializedError(); _initialized[id_] = true; } function _getTraitFromMask(bytes7 mask_, uint8 pos_, uint8 shift_, uint256 max_) internal pure returns(uint8 trait_) { if (shift_ == 0) trait_ = uint8(mask_[pos_]); else if (shift_ == 4) trait_ = uint8(mask_[pos_] >> 4); else trait_ = uint8(mask_[pos_] & 0x0F); if (trait_ >= max_) revert OutOfBondsTraitValueError(); } function _generateSVGfromBytes( MetadataBytes memory data_, Metadata memory metadata_, Image memory image_, Icon memory icon_ ) internal pure returns (bytes memory) { return abi.encodePacked( _getHeader(image_.viewBox, metadata_.backgroundColors[data_.backgroundColors]), _getStyleHeader( metadata_.initialShadowColors[data_.initialShadowColors], metadata_.finalShadowColors[data_.finalShadowColors], metadata_.initialShadowBrightness[data_.initialShadowBrightness], metadata_.finalShadowBrightness[data_.finalShadowBrightness], metadata_.baseFillColors[data_.baseFillColors], metadata_.glowTimes[data_.glowTimes], metadata_.yakFillColors[data_.yakFillColors], metadata_.yakHoverColors[data_.yakHoverColors], metadata_.yakFillColors[data_.yakFillColors] ), image_.path, _getIcon(icon_.path, image_.iconSize), "</svg>" ); } function _getHeader(string memory viewBox_, string memory backgroundColor_) internal pure returns (bytes memory) { return abi.encodePacked( '<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" viewBox="', viewBox_, '" style="background-color:', backgroundColor_, '">' ); } function _getStyleHeader( string memory initialShadowColors_, string memory finalShadowColors_, string memory initialShadowBrightness_, string memory finalShadowBrightness_, string memory baseFillColors_, string memory glowTimes_, string memory yakFillColors_, string memory hoverColors_, string memory iconColor_ ) internal pure returns (bytes memory) { return abi.encodePacked( "<style>", "@keyframes glow {0% {filter: drop-shadow(16px 16px 20px ", initialShadowColors_, ") brightness(", initialShadowBrightness_, "%);}to {filter: drop-shadow(16px 16px 20px ", finalShadowColors_, ") brightness(", finalShadowBrightness_, "%);}}path {fill: ", baseFillColors_, ";animation: glow ", glowTimes_, "s ease-in-out infinite alternate;}.yak {fill: ", yakFillColors_, ";}.yak:hover {fill: ", hoverColors_, ";}.icon {fill: ", iconColor_, ";}</style>" ); } function _getIcon(string memory path_, string memory iconSize_) internal pure returns (bytes memory) { string memory iconLocation_ = " x=\"5%\" y=\"5%\" "; return abi.encodePacked("<svg ", iconSize_, iconLocation_, "> ", path_, "</svg>"); } function _getAttributes(MetadataBytes memory data_, Metadata memory metadata_, string[2] memory names_) internal pure returns (string memory) { return ( string( abi.encodePacked( ' "attributes" : [{ "trait_type": "Character", "value":"', names_[0], '" }, { "trait_type": "Icon", "value": "', names_[1], '"}, { "trait_type": "Background Color", "value": "', metadata_.backgroundColors[data_.backgroundColors], '" }, { "trait_type": "Initial Shadow Color", "value":"', metadata_.initialShadowColors[data_.initialShadowColors], '" }, { "trait_type": "Initial Shadow Brightness", "value":"', metadata_.initialShadowBrightness[data_.initialShadowBrightness], '" }, { "trait_type": "Final Shadow Color ", "value":"', metadata_.finalShadowColors[data_.finalShadowColors], '" }, { "trait_type": "Final Shadow Brightness", "value":"', metadata_.finalShadowBrightness[data_.finalShadowBrightness], '" }, { "trait_type": "Base Fill Colors", "value":"', metadata_.baseFillColors[data_.baseFillColors], '" }, { "trait_type": "Glow Times", "value":"', metadata_.glowTimes[data_.glowTimes], '" }, { "trait_type": "Yak Fill Colors", "value":"', metadata_.yakFillColors[data_.yakFillColors], '" }, { "trait_type": "Hover Colors", "value":"', metadata_.yakHoverColors[data_.yakHoverColors], '" }, { "trait_type": "Rock, Paper, Scissors", "value":"', metadata_.texts[data_.texts], '"} ]' ) ) ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "./IERC721.sol"; import {IERC721Receiver} from "./IERC721Receiver.sol"; import {IERC721Metadata} from "./extensions/IERC721Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {Strings} from "../../utils/Strings.sol"; import {IERC165, ERC165} from "../../utils/introspection/ERC165.sol"; import {IERC721Errors} from "../../interfaces/draft-IERC6093.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors { using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; mapping(uint256 tokenId => address) private _owners; mapping(address owner => uint256) private _balances; mapping(uint256 tokenId => address) private _tokenApprovals; mapping(address owner => mapping(address operator => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual returns (uint256) { if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual returns (string memory) { _requireOwned(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); _checkOnERC721Received(from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { return _tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets * the `spender` for the specific `tokenId`. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { unchecked { _balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { _balances[from] -= 1; } } if (to != address(0)) { unchecked { _balances[to] += 1; } } _owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); _checkOnERC721Received(address(0), to, tokenId, data); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC721 standard to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); _checkOnERC721Received(from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } _tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { if (operator == address(0)) { revert ERC721InvalidOperator(operator); } _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { revert ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { revert ERC721InvalidReceiver(to); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/extensions/ERC721URIStorage.sol) pragma solidity ^0.8.20; import {ERC721} from "../ERC721.sol"; import {Strings} from "../../../utils/Strings.sol"; import {IERC4906} from "../../../interfaces/IERC4906.sol"; import {IERC165} from "../../../interfaces/IERC165.sol"; /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is IERC4906, ERC721 { using Strings for uint256; // Interface ID as defined in ERC-4906. This does not correspond to a traditional interface ID as ERC-4906 only // defines events and does not include any external function. bytes4 private constant ERC4906_INTERFACE_ID = bytes4(0x49064906); // Optional mapping for token URIs mapping(uint256 tokenId => string) private _tokenURIs; /** * @dev See {IERC165-supportsInterface} */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) { return interfaceId == ERC4906_INTERFACE_ID || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireOwned(tokenId); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = _baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via string.concat). if (bytes(_tokenURI).length > 0) { return string.concat(base, _tokenURI); } return super.tokenURI(tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Emits {MetadataUpdate}. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { _tokenURIs[tokenId] = _tokenURI; emit MetadataUpdate(tokenId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol) pragma solidity ^0.8.20; /** * @dev Provides a set of functions to operate with Base64 strings. */ library Base64 { /** * @dev Base64 Encoding/Decoding Table */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // Loads the table into memory string memory table = _TABLE; // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter // and split into 4 numbers of 6 bits. // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up // - `data.length + 2` -> Round up // - `/ 3` -> Number of 3-bytes chunks // - `4 *` -> 4 characters for each chunk string memory result = new string(4 * ((data.length + 2) / 3)); /// @solidity memory-safe-assembly assembly { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 32) // Run over the input, 3 bytes at a time for { let dataPtr := data let endPtr := add(data, mload(data)) } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 bytes (18 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F which is the number of // the previous character in the ASCII table prior to the Base64 Table // The result is then added to the table to get the character to write, // and finally write it in the result pointer but with a left shift // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { SSTORE2 } from "@solmate/src/utils/SSTORE2.sol"; contract ERC721B { uint256 constant MAX_STORAGE = 24_576 - 1; // 1 extra by for stop opcode mapping(bytes32 => address[]) _data; error WriteConflicError(bytes32 id_); function _write(bytes32 id_, bytes calldata data_) internal { if (_data[id_].length != 0) revert WriteConflicError(id_); uint256 dataSize_ = data_.length; uint256 dataPages_ = dataSize_ / MAX_STORAGE + 1; // TODO why + 1? for (uint256 i_; i_ < dataPages_; i_++) { _data[id_].push( SSTORE2.write( data_[i_ * MAX_STORAGE:dataSize_ > (i_ + 1) * MAX_STORAGE ? (i_ + 1) * MAX_STORAGE : dataSize_] ) ); } } function _read(bytes32 id_) internal view returns (bytes memory data_) { uint256 dataPages_ = _data[id_].length; for (uint256 i_; i_ < dataPages_; i_++) { data_ = bytes.concat(data_, SSTORE2.read(_data[id_][i_])); } } }
// SPDX-License-Identifier: Apache-2.0 // TODO pragma solidity ^0.8.20; pragma solidity ^0.8.0; /// @notice Solidity implementation of zlib deflate. /// @dev Optimistic form of: /// https://github.com/adlerjohn/inflate-sol/blob/2a88141f5226da9d0252be4a456a2e0b23ba3d0e/contracts/InflateLib.sol /// @author Zipped Contracts (https://github.com/merklejerk/zipped-contracts) /// @author @adlerjohn (https://github.com/adlerjohn/inflate-sol) (original) contract ZLib { // Maximum bits in a code uint256 constant MAXBITS = 15; // Maximum number of literal/length codes uint256 constant MAXLCODES = 286; // Maximum number of distance codes uint256 constant MAXDCODES = 30; // Maximum codes lengths to read uint256 constant MAXCODES = (MAXLCODES + MAXDCODES); // Number of fixed literal/length codes uint256 constant FIXLCODES = 288; // Error codes error InvalidBlockTypeError(); // invalid block type (type == 3) error InvalidLengthOrDistanceCodeError(); // invalid literal/length or distance code in fixed or dynamic block // Input and output state struct State { ////////////////// // Output state // ////////////////// // Output buffer bytes output; // Bytes written to out so far uint256 outcnt; ///////////////// // Input state // ///////////////// // Bytes read so far uint256 incnt; //////////////// // Temp state // //////////////// // Bit buffer uint256 bitbuf; // Number of bits in bit buffer uint256 bitcnt; // Descriptor code lengths used by _build_dynamic() uint256[] tmpDynamicLengths; // Length and distance codes used by _build_dynamic() Huffman tmpLencode; Huffman tmpDistcode; ////////////////////////// // Static Huffman codes // ////////////////////////// Huffman fixedLencode; Huffman fixedDistcode; ////////////////////////// // Constants (set in puff()) ////////////////////////// // Size base for length codes 257..285 uint16[29] CODES_LENS; // Extra bits for length codes 257..285 uint8[29] CODES_LEXT; // Offset base for distance codes 0..29 uint16[30] CODES_DISTS; // Extra bits for distance codes 0..29 uint8[30] CODES_DEXTS; // Permutation of code length codes uint8[19] BUILD_DYNAMIC_LENGTHS_ORDER; } // Huffman code decoding tables struct Huffman { uint256[] counts; uint256[] symbols; } function _readInputByte(uint256 i) private pure returns (uint8 b) { assembly { let o := add(0x04, calldataload(0x04)) b := shr(248, calldataload(add(o, add(0x20, i)))) } } function _bits(State memory s, uint256 need) private pure returns (uint256 ret) { unchecked { // Bit accumulator (can use up to 20 bits) uint256 val; // Load at least need bits into val val = s.bitbuf; while (s.bitcnt < need) { // Load eight bits val |= uint256(_readInputByte(s.incnt++)) << s.bitcnt; s.bitcnt += 8; } // Drop need bits and update buffer, always zero to seven bits left s.bitbuf = val >> need; s.bitcnt -= need; // Return need bits, zeroing the bits above that ret = (val & ((1 << need) - 1)); } } function _stored(State memory s) private pure { unchecked { // Length of stored block uint256 len; // Discard leftover bits from current byte (assumes s.bitcnt < 8) s.bitbuf = 0; s.bitcnt = 0; // Get length and check against its one's complement len = uint256(_readInputByte(s.incnt++)); len |= uint256(_readInputByte(s.incnt++)) << 8; s.incnt += 2; while (len != 0) { len -= 1; s.output[s.outcnt++] = bytes1(_readInputByte(s.incnt++)); } } } function _decode(State memory s, Huffman memory h) private pure returns (uint256) { unchecked { // Current number of bits in code uint256 len; // Len bits being decoded uint256 code = 0; // First code of length len uint256 first = 0; // Number of codes of length len uint256 count; // Index of first code of length len in symbol table uint256 index = 0; for (len = 1; len <= MAXBITS; len++) { // Get next bit uint256 tempCode; tempCode = _bits(s, 1); code |= tempCode; count = h.counts[len]; // If length len, return symbol if (code < first + count) { return h.symbols[index + (code - first)]; } // Else update for next length index += count; first += count; first <<= 1; code <<= 1; } // Ran out of codes revert InvalidLengthOrDistanceCodeError(); } } function _construct(Huffman memory h, uint256[] memory lengths, uint256 n, uint256 start) private pure { unchecked { // Current symbol when stepping through lengths[] uint256 symbol; // Current length when stepping through h.counts[] uint256 len; // Number of possible codes left of current length uint256 left; // Offsets in symbol table for each length uint256[MAXBITS + 1] memory offs; // Count number of codes of each length for (len = 0; len <= MAXBITS; len++) { h.counts[len] = 0; } for (symbol = 0; symbol < n; symbol++) { // Assumes lengths are within bounds h.counts[lengths[start + symbol]]++; } // No codes! if (h.counts[0] == n) { // Complete, but decode() will fail return; } // Check for an over-subscribed or incomplete set of lengths // One possible code of zero length left = 1; offs[1] = 0; for (len = 1; len <= MAXBITS; len++) { // One more bit, double codes left left <<= 1; // Deduct count from possible codes left -= h.counts[len]; // Generate offsets into symbol table for each length for sorting if (len < MAXBITS) { offs[len + 1] = offs[len] + h.counts[len]; } } // Put symbols in table sorted by length, by symbol order within each length for (symbol = 0; symbol < n; symbol++) { if (lengths[start + symbol] != 0) { h.symbols[offs[lengths[start + symbol]]++] = symbol; } } } } function _codes(State memory s, Huffman memory lencode, Huffman memory distcode) private pure { unchecked { // Decoded symbol uint256 symbol; // Length for copy uint256 len; // Distance for copy uint256 dist; // Size base for length codes 257..285 uint16[29] memory lens = s.CODES_LENS; // Extra bits for length codes 257..285 uint8[29] memory lext = s.CODES_LEXT; // Offset base for distance codes 0..29 uint16[30] memory dists = s.CODES_DISTS; // Extra bits for distance codes 0..29 uint8[30] memory dext = s.CODES_DEXTS; // Decode literals and length/distance pairs while (symbol != 256) { symbol = _decode(s, lencode); if (symbol < 256) { // Literal: symbol is the byte // Write out the literal s.output[s.outcnt] = bytes1(uint8(symbol)); s.outcnt++; } else if (symbol > 256) { uint256 tempBits; // Length // Get and compute length symbol -= 257; tempBits = _bits(s, lext[symbol]); len = lens[symbol] + tempBits; // Get and check distance symbol = _decode(s, distcode); tempBits = _bits(s, dext[symbol]); dist = dists[symbol] + tempBits; // Copy length bytes from distance bytes back bytes memory output = s.output; uint256 outcnt = s.outcnt; s.outcnt += len; assembly ("memory-safe") { let dst := add(output, add(0x20, outcnt)) switch gt(len, dist) case 1 { for { } iszero(iszero(len)) { } { mstore(dst, mload(sub(dst, dist))) len := sub(len, 0x01) dst := add(dst, 0x01) } } default { for { } iszero(iszero(len)) { } { mstore(dst, mload(sub(dst, dist))) switch gt(len, 0x20) case 1 { len := sub(len, 0x20) dst := add(dst, 0x20) } default { len := 0 } } } } } else { s.outcnt += len; } } } } function _build_fixed(State memory s) private pure { unchecked { // Build fixed Huffman tables // TODO this is all a compile-time constant uint256 symbol; uint256[] memory lengths = new uint256[](FIXLCODES); // Literal/length table for (symbol = 0; symbol < 144; symbol++) { lengths[symbol] = 8; } for (; symbol < 256; symbol++) { lengths[symbol] = 9; } for (; symbol < 280; symbol++) { lengths[symbol] = 7; } for (; symbol < FIXLCODES; symbol++) { lengths[symbol] = 8; } _construct(s.fixedLencode, lengths, FIXLCODES, 0); // Distance table for (symbol = 0; symbol < MAXDCODES; symbol++) { lengths[symbol] = 5; } _construct(s.fixedDistcode, lengths, MAXDCODES, 0); } } function _fixed(State memory s) private pure { // Decode data until end-of-block code _codes(s, s.fixedLencode, s.fixedDistcode); } function _build_dynamic_lengths(State memory s) private pure returns (uint256[] memory) { unchecked { uint256 ncode; // Index of lengths[] uint256 index; ncode = _bits(s, 4); ncode += 4; // Read code length code lengths (really), missing lengths are zero for (index = 0; index < ncode; index++) { s.tmpDynamicLengths[s.BUILD_DYNAMIC_LENGTHS_ORDER[index]] = _bits(s, 3); } for (; index < 19; index++) { s.tmpDynamicLengths[s.BUILD_DYNAMIC_LENGTHS_ORDER[index]] = 0; } return s.tmpDynamicLengths; } } function _build_dynamic(State memory s) private pure returns (Huffman memory, Huffman memory) { unchecked { // Number of lengths in descriptor uint256 nlen; uint256 ndist; // Length and distance codes Huffman memory lencode = s.tmpLencode; Huffman memory distcode = s.tmpDistcode; uint256 tempBits; // Get number of lengths in each table, check lengths nlen = _bits(s, 5); nlen += 257; ndist = _bits(s, 5); ndist += 1; // Descriptor code lengths uint256[] memory lengths = _build_dynamic_lengths(s); // Build huffman table for code lengths codes (use lencode temporarily) _construct(lencode, lengths, 19, 0); // Index of lengths[] uint256 index = 0; // Read length/literal and distance code length tables while (index < nlen + ndist) { // Decoded value uint256 symbol; // Last length to repeat uint256 len; symbol = _decode(s, lencode); if (symbol < 16) { // Length in 0..15 lengths[index++] = symbol; } else { // Repeat instruction // Assume repeating zeros len = 0; if (symbol == 16) { // Repeat last length 3..6 times // Last length len = lengths[index - 1]; tempBits = _bits(s, 2); symbol = 3 + tempBits; } else if (symbol == 17) { // Repeat zero 3..10 times tempBits = _bits(s, 3); symbol = 3 + tempBits; } else { // == 18, repeat zero 11..138 times tempBits = _bits(s, 7); symbol = 11 + tempBits; } assembly ("memory-safe") { let p := add(lengths, add(0x20, mul(index, 0x20))) index := add(index, symbol) for { } iszero(iszero(symbol)) { } { mstore(p, len) symbol := sub(symbol, 1) p := add(p, 0x20) } } } } // Build huffman table for literal/length codes _construct(lencode, lengths, nlen, 0); // Build huffman table for distance codes _construct(distcode, lengths, ndist, nlen); return (lencode, distcode); } } function _dynamic(State memory s) private pure { // Length and distance codes Huffman memory lencode; Huffman memory distcode; (lencode, distcode) = _build_dynamic(s); // Decode data until end-of-block code _codes(s, lencode, distcode); } function inflate(bytes calldata, /* input */ uint256 outputSize) external pure returns (bytes memory) { // Input/output state State memory s = State({ output: new bytes(outputSize), outcnt: 0, incnt: 0, bitbuf: 0, bitcnt: 0, tmpDynamicLengths: new uint256[](MAXCODES), tmpLencode: Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXCODES)), tmpDistcode: Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXCODES)), fixedLencode: Huffman(new uint256[](MAXBITS + 1), new uint256[](FIXLCODES)), fixedDistcode: Huffman(new uint256[](MAXBITS + 1), new uint256[](MAXDCODES)), CODES_LENS: [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 ], CODES_LEXT: [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0], CODES_DISTS: [ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12_289, 16_385, 24_577 ], CODES_DEXTS: [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13], BUILD_DYNAMIC_LENGTHS_ORDER: [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15] }); // Temp: last bit uint256 last; // Temp: block type bit uint256 t; // Build fixed Huffman tables _build_fixed(s); // Process blocks until last block or error while (last == 0) { // One if last block last = _bits(s, 1); // Block type 0..3 t = _bits(s, 2); if (t == 0) { _stored(s); } else if (t == 1) { _fixed(s); } else if (t == 2) { _dynamic(s); } else { revert InvalidBlockTypeError(); } } return s.output; } function inflateFrom(address dataAddr, uint256 dataOffset, uint256 dataSize, uint256 outputSize) external view returns (bytes memory) { bytes memory data = new bytes(dataSize); assembly ("memory-safe") { extcodecopy(dataAddr, add(data, 0x20), dataOffset, dataSize) } return this.inflate(data, outputSize); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.20; import {IERC721} from "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC4906.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; import {IERC721} from "./IERC721.sol"; /// @title EIP-721 Metadata Update Extension interface IERC4906 is IERC165, IERC721 { /// @dev This event emits when the metadata of a token is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFT. event MetadataUpdate(uint256 _tokenId); /// @dev This event emits when the metadata of a range of tokens is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFTs. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Read and write to persistent storage at a fraction of the cost. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol) /// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol) library SSTORE2 { uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called. /*////////////////////////////////////////////////////////////// WRITE LOGIC //////////////////////////////////////////////////////////////*/ function write(bytes memory data) internal returns (address pointer) { // Prefix the bytecode with a STOP opcode to ensure it cannot be called. bytes memory runtimeCode = abi.encodePacked(hex"00", data); bytes memory creationCode = abi.encodePacked( //---------------------------------------------------------------------------------------------------------------// // Opcode | Opcode + Arguments | Description | Stack View // //---------------------------------------------------------------------------------------------------------------// // 0x60 | 0x600B | PUSH1 11 | codeOffset // // 0x59 | 0x59 | MSIZE | 0 codeOffset // // 0x81 | 0x81 | DUP2 | codeOffset 0 codeOffset // // 0x38 | 0x38 | CODESIZE | codeSize codeOffset 0 codeOffset // // 0x03 | 0x03 | SUB | (codeSize - codeOffset) 0 codeOffset // // 0x80 | 0x80 | DUP | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset // // 0x92 | 0x92 | SWAP3 | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // // 0x59 | 0x59 | MSIZE | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) // // 0x39 | 0x39 | CODECOPY | 0 (codeSize - codeOffset) // // 0xf3 | 0xf3 | RETURN | // //---------------------------------------------------------------------------------------------------------------// hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes. runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit. ); /// @solidity memory-safe-assembly assembly { // Deploy a new contract with the generated creation code. // We start 32 bytes into the code to avoid copying the byte length. pointer := create(0, add(creationCode, 32), mload(creationCode)) } require(pointer != address(0), "DEPLOYMENT_FAILED"); } /*////////////////////////////////////////////////////////////// READ LOGIC //////////////////////////////////////////////////////////////*/ function read(address pointer) internal view returns (bytes memory) { return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET); } function read(address pointer, uint256 start) internal view returns (bytes memory) { start += DATA_OFFSET; return readBytecode(pointer, start, pointer.code.length - start); } function read( address pointer, uint256 start, uint256 end ) internal view returns (bytes memory) { start += DATA_OFFSET; end += DATA_OFFSET; require(pointer.code.length >= end, "OUT_OF_BOUNDS"); return readBytecode(pointer, start, end - start); } /*////////////////////////////////////////////////////////////// INTERNAL HELPER LOGIC //////////////////////////////////////////////////////////////*/ function readBytecode( address pointer, uint256 start, uint256 size ) private view returns (bytes memory data) { /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. data := mload(0x40) // Update the free memory pointer to prevent overriding our data. // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)). // Adding 31 to size and running the result through the logic above ensures // the memory pointer remains word-aligned, following the Solidity convention. mstore(0x40, add(data, and(add(add(size, 32), 31), not(31)))) // Store the size of the data in the first 32 byte chunk of free memory. mstore(data, size) // Copy the code into memory right after the 32 bytes we used to store the size. extcodecopy(pointer, add(data, 32), start, size) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "../token/ERC721/IERC721.sol";
{ "remappings": [ "@forge-std/=lib/forge-std/src/", "@openzeppelin/=lib/openzeppelin-contracts/", "@solmate/=lib/solmate/", "@base64WithDecode/=lib/Base64.sol/contracts/", "@forge-std/=lib/mezzanote-sale/lib/forge-std/src/", "@openzeppelin/=lib/mezzanote-sale/lib/openzeppelin-contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "Base64.sol/=lib/Base64.sol/contracts/", "ds-test/=lib/solmate/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "mezzanote-sale/=lib/mezzanote-sale/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/", "zipped-contracts/=lib/zipped-contracts/" ], "optimizer": { "enabled": false, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"zlib_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitializedError","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"NotSaleContractError","type":"error"},{"inputs":[],"name":"OutOfBondsTraitValueError","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"bytes32","name":"id_","type":"bytes32"}],"name":"WriteConflicError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"generateSVGfromBytes","outputs":[{"internalType":"string","name":"svg_","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"icons_","type":"bytes[]"},{"internalType":"uint128[]","name":"decompressedSizesIcons_","type":"uint128[]"}],"name":"initializeIcons","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"images_","type":"bytes[]"},{"internalType":"uint128[]","name":"decompressedSizes_","type":"uint128[]"}],"name":"initializeImages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"images_","type":"bytes[]"},{"internalType":"uint128[]","name":"decompressedSizes_","type":"uint128[]"},{"internalType":"uint256","name":"totalImages_","type":"uint256"}],"name":"initializeImagesHardcoded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"metadata_","type":"bytes"},{"internalType":"bytes7","name":"sampleImageTraits_","type":"bytes7"}],"name":"initializeMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes7","name":"metadataInfo_","type":"bytes7"}],"name":"processMetadataAsBytes","outputs":[{"components":[{"internalType":"uint8","name":"glowTimes","type":"uint8"},{"internalType":"uint8","name":"backgroundColors","type":"uint8"},{"internalType":"uint8","name":"yakHoverColors","type":"uint8"},{"internalType":"uint8","name":"finalShadowColors","type":"uint8"},{"internalType":"uint8","name":"baseFillColors","type":"uint8"},{"internalType":"uint8","name":"yakFillColors","type":"uint8"},{"internalType":"uint8","name":"yak","type":"uint8"},{"internalType":"uint8","name":"initialShadowColors","type":"uint8"},{"internalType":"uint8","name":"initialShadowBrightness","type":"uint8"},{"internalType":"uint8","name":"finalShadowBrightness","type":"uint8"},{"internalType":"uint8","name":"icon","type":"uint8"},{"internalType":"uint8","name":"texts","type":"uint8"}],"internalType":"struct Yakyuken.MetadataBytes","name":"data_","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes7[]","name":"imageTraits_","type":"bytes7[]"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sale_","type":"address"}],"name":"setSaleContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId_","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162006fbf38038062006fbf833981810160405281019062000037919062000b52565b336040518060400160405280600881526020017f59616b79756b656e0000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f594e4654000000000000000000000000000000000000000000000000000000008152508160019081620000b5919062000dfe565b508060029081620000c7919062000dfe565b505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200013f5760006040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040162000136919062000ef6565b60405180910390fd5b6200015081620001c260201b60201c565b508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505060005b6019811015620001ba57620001a433826200028860201b60201c565b8080620001b19062000f42565b91505062000188565b505062000fea565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603620002fd5760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401620002f4919062000ef6565b60405180910390fd5b600062000313838360006200038f60201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146200038a5760006040517f73c6ac6e00000000000000000000000000000000000000000000000000000000815260040162000381919062000ef6565b60405180910390fd5b505050565b600080620003a384620005c460201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614620003ee57620003ed8184866200060160201b60201c565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614620004885762000439600085600080620006d360201b60201c565b6001600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146200050c576001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846003600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b60006003600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b62000614838383620008b060201b60201c565b620006ce57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036200068d57806040517f7e27328900000000000000000000000000000000000000000000000000000000815260040162000684919062000fa0565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401620006c592919062000fbd565b60405180910390fd5b505050565b80806200070d5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156200085857600062000726846200098460201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156200079257508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015620007ae5750620007ac818462000a1760201b60201c565b155b15620007f357826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401620007ea919062000ef6565b60405180910390fd5b81156200085657838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836005600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156200097b57508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148062000933575062000932848462000a1760201b60201c565b5b806200097a57508273ffffffffffffffffffffffffffffffffffffffff16620009628362000aab60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b6000806200099883620005c460201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000a0e57826040517f7e27328900000000000000000000000000000000000000000000000000000000815260040162000a05919062000fa0565b60405180910390fd5b80915050919050565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60006005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000b1a8262000aed565b9050919050565b62000b2c8162000b0d565b811462000b3857600080fd5b50565b60008151905062000b4c8162000b21565b92915050565b60006020828403121562000b6b5762000b6a62000ae8565b5b600062000b7b8482850162000b3b565b91505092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000c0657607f821691505b60208210810362000c1c5762000c1b62000bbe565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830262000c867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000c47565b62000c92868362000c47565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000cdf62000cd962000cd38462000caa565b62000cb4565b62000caa565b9050919050565b6000819050919050565b62000cfb8362000cbe565b62000d1362000d0a8262000ce6565b84845462000c54565b825550505050565b600090565b62000d2a62000d1b565b62000d3781848462000cf0565b505050565b5b8181101562000d5f5762000d5360008262000d20565b60018101905062000d3d565b5050565b601f82111562000dae5762000d788162000c22565b62000d838462000c37565b8101602085101562000d93578190505b62000dab62000da28562000c37565b83018262000d3c565b50505b505050565b600082821c905092915050565b600062000dd36000198460080262000db3565b1980831691505092915050565b600062000dee838362000dc0565b9150826002028217905092915050565b62000e098262000b84565b67ffffffffffffffff81111562000e255762000e2462000b8f565b5b62000e31825462000bed565b62000e3e82828562000d63565b600060209050601f83116001811462000e76576000841562000e61578287015190505b62000e6d858262000de0565b86555062000edd565b601f19841662000e868662000c22565b60005b8281101562000eb05784890151825560018201915060208501945060208101905062000e89565b8683101562000ed0578489015162000ecc601f89168262000dc0565b8355505b6001600288020188555050505b505050505050565b62000ef08162000b0d565b82525050565b600060208201905062000f0d600083018462000ee5565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000f4f8262000caa565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362000f845762000f8362000f13565b5b600182019050919050565b62000f9a8162000caa565b82525050565b600060208201905062000fb7600083018462000f8f565b92915050565b600060408201905062000fd4600083018562000ee5565b62000fe3602083018462000f8f565b9392505050565b608051615fa46200101b60003960008181610f380152818161106e015281816114e6015261161c0152615fa46000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c806370a08231116100de578063b88d4fde11610097578063efde823711610071578063efde823714610444578063efeee06d14610460578063f2fde38b14610490578063fea7dec7146104ac57610173565b8063b88d4fde146103c8578063c87b56dd146103e4578063e985e9c51461041457610173565b806370a082311461031a578063715018a61461034a5780637dcd47e0146103545780638da5cb5b1461037057806395d89b411461038e578063a22cb465146103ac57610173565b80633393450b116101305780633393450b1461024a5780633f5f96c01461026657806340c10f191461029657806342842e0e146102b257806352956954146102ce5780636352211e146102ea57610173565b806301ffc9a7146101785780630593d244146101a857806306fdde03146101c4578063081812fc146101e2578063095ea7b31461021257806323b872dd1461022e575b600080fd5b610192600480360381019061018d9190613464565b6104c8565b60405161019f91906134ac565b60405180910390f35b6101c260048036038101906101bd9190613525565b610529565b005b6101cc610575565b6040516101d991906135e2565b60405180910390f35b6101fc60048036038101906101f7919061363a565b610607565b6040516102099190613676565b60405180910390f35b61022c60048036038101906102279190613691565b610623565b005b610248600480360381019061024391906136d1565b610639565b005b610264600480360381019061025f91906137e1565b61073b565b005b610280600480360381019061027b9190613841565b6107a0565b60405161028d9190613980565b60405180910390f35b6102b060048036038101906102ab9190613691565b6109a2565b005b6102cc60048036038101906102c791906136d1565b610a37565b005b6102e860048036038101906102e39190613a48565b610a57565b005b61030460048036038101906102ff919061363a565b610b7a565b6040516103119190613676565b60405180910390f35b610334600480360381019061032f9190613525565b610b8c565b6040516103419190613ad8565b60405180910390f35b610352610c46565b005b61036e60048036038101906103699190613af3565b610c5a565b005b610378610d97565b6040516103859190613676565b60405180910390f35b610396610dc1565b6040516103a391906135e2565b60405180910390f35b6103c660048036038101906103c19190613bb4565b610e53565b005b6103e260048036038101906103dd9190613d24565b610e69565b005b6103fe60048036038101906103f9919061363a565b610e86565b60405161040b91906135e2565b60405180910390f35b61042e60048036038101906104299190613da7565b61126d565b60405161043b91906134ac565b60405180910390f35b61045e60048036038101906104599190613a48565b611301565b005b61047a6004803603810190610475919061363a565b611434565b60405161048791906135e2565b60405180910390f35b6104aa60048036038101906104a59190613525565b611776565b005b6104c660048036038101906104c19190613eaa565b6117fc565b005b6000634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061052257506105218261181e565b5b9050919050565b610531611900565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60606001805461058490613f22565b80601f01602080910402602001604051908101604052809291908181526020018280546105b090613f22565b80156105fd5780601f106105d2576101008083540402835291602001916105fd565b820191906000526020600020905b8154815290600101906020018083116105e057829003601f168201915b5050505050905090565b600061061282611987565b5061061c82611a0f565b9050919050565b6106358282610630611a4c565b611a54565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036106ab5760006040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016106a29190613676565b60405180910390fd5b60006106bf83836106ba611a4c565b611a66565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610735578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161072c93929190613f53565b60405180910390fd5b50505050565b610743611900565b600061074e81611c80565b6107797f7a9d3a032b8ff274f09714b56ba8e5ed776ec9638ca303069bc3a3267bb22f658585611d19565b81600c60006101000a81548166ffffffffffffff021916908360c81c021790555050505050565b6107a86132a3565b60006107d37f7a9d3a032b8ff274f09714b56ba8e5ed776ec9638ca303069bc3a3267bb22f65611edb565b8060200190518101906107e69190614324565b90506107fa83600080846080015151611f96565b826000019060ff16908160ff168152505061081e8360016000846000015151611f96565b826020019060ff16908160ff1681525050610843836002600484610120015151611f96565b826040019060ff16908160ff1681525050610867836002600a846060015151611f96565b826060019060ff16908160ff168152505061088b8360036004846020015151611f96565b826080019060ff16908160ff16815250506108b0836003600a84610100015151611f96565b8260a0019060ff16908160ff16815250506108d383600480600980549050611f96565b8260c0019060ff16908160ff16815250506108f7836004600a8460c0015151611f96565b8260e0019060ff16908160ff168152505061091b83600560048460a0015151611f96565b82610100019060ff16908160ff1681525050610940836005600a846040015151611f96565b82610120019060ff16908160ff16815250506109658360066004600a80549050611f96565b82610140019060ff16908160ff168152505061098a836006600a8460e0015151611f96565b82610160019060ff16908160ff168152505050919050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a29576040517f179b043d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a338282612086565b5050565b610a5283838360405180602001604052806000815250610e69565b505050565b610a5f611900565b6001610a6a81611c80565b600085859050905060005b81811015610b7157610ad181604051602001610a919190613ad8565b60405160208183030381529060405280519060200120888884818110610aba57610ab961436d565b5b9050602002810190610acc91906143ab565b611d19565b6009858583818110610ae657610ae561436d565b5b9050602002016020810190610afb9190614456565b90806001815401808255809150506001900390600052602060002090600291828204019190066010029091909190916101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508080610b69906144b2565b915050610a75565b50505050505050565b6000610b8582611987565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bff5760006040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610bf69190613676565b60405180910390fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610c4e611900565b610c58600061217f565b565b610c62611900565b6002610c6d81611c80565b60008686905083610c7e91906144fa565b905060005b87879050811015610d8d57610ced8282610c9d919061452e565b604051602001610cad9190613ad8565b60405160208183030381529060405280519060200120898984818110610cd657610cd561436d565b5b9050602002810190610ce891906143ab565b611d19565b6009868683818110610d0257610d0161436d565b5b9050602002016020810190610d179190614456565b90806001815401808255809150506001900390600052602060002090600291828204019190066010029091909190916101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508080610d85906144b2565b915050610c83565b5050505050505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060028054610dd090613f22565b80601f0160208091040260200160405190810160405280929190818152602001828054610dfc90613f22565b8015610e495780601f10610e1e57610100808354040283529160200191610e49565b820191906000526020600020905b815481529060010190602001808311610e2c57829003601f168201915b5050505050905090565b610e65610e5e611a4c565b8383612245565b5050565b610e74848484610639565b610e80848484846123b4565b50505050565b6060610e906132a3565b610ef26000600b8054905011610eb557600c60009054906101000a900460c81b610eed565b600b8481548110610ec957610ec861436d565b5b90600052602060002090600491828204019190066007029054906101000a900460c81b5b6107a0565b90506000610f1f7f7a9d3a032b8ff274f09714b56ba8e5ed776ec9638ca303069bc3a3267bb22f65611edb565b806020019051810190610f329190614324565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637b631b69610fa58560c00151604051602001610f8a9190614571565b60405160208183030381529060405280519060200120611edb565b60098660c0015160ff1681548110610fc057610fbf61436d565b5b90600052602060002090600291828204019190066010029054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161100f92919061461c565b600060405180830381865afa15801561102c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061105591906146bc565b806020019051810190611068919061481d565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637b631b696110eb606487610140015160ff166110c09190614874565b6040516020016110d091906148b9565b60405160208183030381529060405280519060200120611edb565b600a87610140015160ff16815481106111075761110661436d565b5b90600052602060002090600291828204019190066010029054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161115692919061461c565b600060405180830381865afa158015611173573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061119c91906146bc565b8060200190518101906111af919061498c565b905060006111bc8761256b565b6111d06111cb87878787612639565b612814565b6040516020016111e09190614a5d565b60405160208183030381529060405261121687876040518060400160405280896080015181526020018860200151815250612977565b60405160200161122893929190614cb9565b604051602081830303815290604052905061124281612814565b6040516020016112529190614d83565b60405160208183030381529060405295505050505050919050565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611309611900565b600361131481611c80565b600085859050905060005b8181101561142b5761138b606461ffff168261133b919061452e565b60405160200161134b9190613ad8565b604051602081830303815290604052805190602001208888848181106113745761137361436d565b5b905060200281019061138691906143ab565b611d19565b600a8585838181106113a05761139f61436d565b5b90506020020160208101906113b59190614456565b90806001815401808255809150506001900390600052602060002090600291828204019190066010029091909190916101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508080611423906144b2565b91505061131f565b50505050505050565b606061143e6132a3565b6114a06000600b805490501161146357600c60009054906101000a900460c81b61149b565b600b84815481106114775761147661436d565b5b90600052602060002090600491828204019190066007029054906101000a900460c81b5b6107a0565b905060006114cd7f7a9d3a032b8ff274f09714b56ba8e5ed776ec9638ca303069bc3a3267bb22f65611edb565b8060200190518101906114e09190614324565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637b631b696115538560c001516040516020016115389190614571565b60405160208183030381529060405280519060200120611edb565b60098660c0015160ff168154811061156e5761156d61436d565b5b90600052602060002090600291828204019190066010029054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b81526004016115bd92919061461c565b600060405180830381865afa1580156115da573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061160391906146bc565b806020019051810190611616919061481d565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637b631b69611699606487610140015160ff1661166e9190614874565b60405160200161167e91906148b9565b60405160208183030381529060405280519060200120611edb565b600a87610140015160ff16815481106116b5576116b461436d565b5b90600052602060002090600291828204019190066010029054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161170492919061461c565b600060405180830381865afa158015611721573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061174a91906146bc565b80602001905181019061175d919061498c565b905061176b84848484612639565b945050505050919050565b61177e611900565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036117f05760006040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016117e79190613676565b60405180910390fd5b6117f98161217f565b50565b611804611900565b80600b908051906020019061181a929190613328565b5050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806118e957507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806118f957506118f882612b5f565b5b9050919050565b611908611a4c565b73ffffffffffffffffffffffffffffffffffffffff16611926610d97565b73ffffffffffffffffffffffffffffffffffffffff161461198557611949611a4c565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161197c9190613676565b60405180910390fd5b565b60008061199383612bc9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a0657826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016119fd9190613ad8565b60405180910390fd5b80915050919050565b60006005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600033905090565b611a618383836001612c06565b505050565b600080611a7284612bc9565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611ab457611ab3818486612dcb565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b4557611af6600085600080612c06565b6001600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611bc8576001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846003600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b600d8160048110611c9457611c9361436d565b5b602091828204019190069054906101000a900460ff1615611ce1576040517f2e60c66000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600d8260048110611cf757611cf661436d565b5b602091828204019190066101000a81548160ff02191690831515021790555050565b60008060008581526020019081526020016000208054905014611d7357826040517f39474a48000000000000000000000000000000000000000000000000000000008152600401611d6a9190614dbe565b60405180910390fd5b600082829050905060006001615fff83611d8d9190614e08565b611d97919061452e565b905060005b81811015611ed357600080878152602001908152602001600020611e608686615fff85611dc99190614e39565b90615fff600187611dda919061452e565b611de49190614e39565b8811611df05787611e0b565b615fff600187611e00919061452e565b611e0a9190614e39565b5b92611e1893929190614e85565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e8f565b9080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508080611ecb906144b2565b915050611d9c565b505050505050565b6060600080600084815260200190815260200160002080549050905060005b81811015611f8f5782611f5a6000808781526020019081526020016000208381548110611f2a57611f2961436d565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612f59565b604051602001611f6b929190614efc565b60405160208183030381529060405292508080611f87906144b2565b915050611efa565b5050919050565b6000808360ff1603611fc657848460ff1660078110611fb857611fb761436d565b5b1a60f81b60f81c9050612042565b60048360ff160361201b576004858560ff1660078110611fe957611fe861436d565b5b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c9050612041565b600f60f81b858560ff16600781106120365761203561436d565b5b1a60f81b1660f81c90505b5b818160ff161061207e576040517f32064cab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036120f85760006040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016120ef9190613676565b60405180910390fd5b600061210683836000611a66565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461217a5760006040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016121719190613676565b60405180910390fd5b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036122b657816040517f5b08ba180000000000000000000000000000000000000000000000000000000081526004016122ad9190613676565b60405180910390fd5b80600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123a791906134ac565b60405180910390a3505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b1115612565578273ffffffffffffffffffffffffffffffffffffffff1663150b7a026123f8611a4c565b8685856040518563ffffffff1660e01b815260040161241a9493929190614f20565b6020604051808303816000875af192505050801561245657506040513d601f19601f820116820180604052508101906124539190614f81565b60015b6124da573d8060008114612486576040519150601f19603f3d011682016040523d82523d6000602084013e61248b565b606091505b5060008151036124d257836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016124c99190613676565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461256357836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161255a9190613676565b60405180910390fd5b505b50505050565b60606000600161257a84612f90565b01905060008167ffffffffffffffff81111561259957612598613bf9565b5b6040519080825280601f01601f1916602001820160405280156125cb5781602001600182028036833780820191505090505b509050600082602001820190505b60011561262e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161262257612621614dd9565b5b049450600085036125d9575b819350505050919050565b606061266e83602001518560000151876020015160ff16815181106126615761266061436d565b5b60200260200101516130e3565b6127d18560c001518760e0015160ff168151811061268f5761268e61436d565b5b60200260200101518660600151886060015160ff16815181106126b5576126b461436d565b5b60200260200101518760a0015189610100015160ff16815181106126dc576126db61436d565b5b602002602001015188604001518a610120015160ff16815181106127035761270261436d565b5b602002602001015189602001518b6080015160ff16815181106127295761272861436d565b5b60200260200101518a608001518c6000015160ff168151811061274f5761274e61436d565b5b60200260200101518b61010001518d60a0015160ff16815181106127765761277561436d565b5b60200260200101518c61012001518e6040015160ff168151811061279d5761279c61436d565b5b60200260200101518d61010001518f60a0015160ff16815181106127c4576127c361436d565b5b602002602001015161310f565b84600001516127e885604001518760600151613150565b6040516020016127fb9493929190614ffa565b6040516020818303038152906040529050949350505050565b6060600082510361283657604051806020016040528060008152509050612972565b6000604051806060016040528060408152602001615f2f6040913990506000600360028551612865919061452e565b61286f9190614e08565b600461287b9190614e39565b67ffffffffffffffff81111561289457612893613bf9565b5b6040519080825280601f01601f1916602001820160405280156128c65781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015612932576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506128d7565b505060038651066001811461294e576002811461296157612969565b603d6001830353603d6002830353612969565b603d60018303535b50505080925050505b919050565b60608160006002811061298d5761298c61436d565b5b6020020151826001600281106129a6576129a561436d565b5b60200201518460000151866020015160ff16815181106129c9576129c861436d565b5b60200260200101518560c001518760e0015160ff16815181106129ef576129ee61436d565b5b60200260200101518660a0015188610100015160ff1681518110612a1657612a1561436d565b5b60200260200101518760600151896060015160ff1681518110612a3c57612a3b61436d565b5b602002602001015188604001518a610120015160ff1681518110612a6357612a6261436d565b5b602002602001015189602001518b6080015160ff1681518110612a8957612a8861436d565b5b60200260200101518a608001518c6000015160ff1681518110612aaf57612aae61436d565b5b60200260200101518b61010001518d60a0015160ff1681518110612ad657612ad561436d565b5b60200260200101518c61012001518e6040015160ff1681518110612afd57612afc61436d565b5b60200260200101518d60e001518f610160015160ff1681518110612b2457612b2361436d565b5b6020026020010151604051602001612b479c9b9a999897969594939291906155e7565b60405160208183030381529060405290509392505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60006003600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8080612c3f5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15612d73576000612c4f84611987565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015612cba57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015612ccd5750612ccb818461126d565b155b15612d0f57826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401612d069190613676565b60405180910390fd5b8115612d7157838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836005600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b612dd68383836131b9565b612e8a57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612e4b57806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401612e429190613ad8565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401612e8192919061571c565b60405180910390fd5b505050565b60008082604051602001612ea39190615771565b6040516020818303038152906040529050600081604051602001612ec791906157df565b60405160208183030381529060405290508051602082016000f09250600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612f52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f499061584d565b60405180910390fd5b5050919050565b6060612f89826001808573ffffffffffffffffffffffffffffffffffffffff163b612f8491906144fa565b61327a565b9050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612fee577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612fe457612fe3614dd9565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061302b576d04ee2d6d415b85acef8100000000838161302157613020614dd9565b5b0492506020810190505b662386f26fc10000831061305a57662386f26fc1000083816130505761304f614dd9565b5b0492506010810190505b6305f5e1008310613083576305f5e100838161307957613078614dd9565b5b0492506008810190505b61271083106130a857612710838161309e5761309d614dd9565b5b0492506004810190505b606483106130cb57606483816130c1576130c0614dd9565b5b0492506002810190505b600a83106130da576001810190505b80915050919050565b606082826040516020016130f892919061599d565b604051602081830303815290604052905092915050565b606089888a89898989898960405160200161313299989796959493929190615d4c565b60405160208183030381529060405290509998505050505050505050565b606060006040518060400160405280600f81526020017f20783d2235252220793d2235252220000000000000000000000000000000000081525090508281856040516020016131a193929190615edc565b60405160208183030381529060405291505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561327157508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806132325750613231848461126d565b5b8061327057508273ffffffffffffffffffffffffffffffffffffffff1661325883611a0f565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b60606040519050601f19601f6020840101168101604052818152818360208301863c9392505050565b604051806101800160405280600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff1681525090565b828054828255906000526020600020906003016004900481019282156133ca5791602002820160005b8382111561339557835183826101000a81548166ffffffffffffff021916908360c81c02179055509260200192600701602081600601049283019260010302613351565b80156133c85782816101000a81549066ffffffffffffff0219169055600701602081600601049283019260010302613395565b505b5090506133d791906133db565b5090565b5b808211156133f45760008160009055506001016133dc565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6134418161340c565b811461344c57600080fd5b50565b60008135905061345e81613438565b92915050565b60006020828403121561347a57613479613402565b5b60006134888482850161344f565b91505092915050565b60008115159050919050565b6134a681613491565b82525050565b60006020820190506134c1600083018461349d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006134f2826134c7565b9050919050565b613502816134e7565b811461350d57600080fd5b50565b60008135905061351f816134f9565b92915050565b60006020828403121561353b5761353a613402565b5b600061354984828501613510565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561358c578082015181840152602081019050613571565b60008484015250505050565b6000601f19601f8301169050919050565b60006135b482613552565b6135be818561355d565b93506135ce81856020860161356e565b6135d781613598565b840191505092915050565b600060208201905081810360008301526135fc81846135a9565b905092915050565b6000819050919050565b61361781613604565b811461362257600080fd5b50565b6000813590506136348161360e565b92915050565b6000602082840312156136505761364f613402565b5b600061365e84828501613625565b91505092915050565b613670816134e7565b82525050565b600060208201905061368b6000830184613667565b92915050565b600080604083850312156136a8576136a7613402565b5b60006136b685828601613510565b92505060206136c785828601613625565b9150509250929050565b6000806000606084860312156136ea576136e9613402565b5b60006136f886828701613510565b935050602061370986828701613510565b925050604061371a86828701613625565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f84011261374957613748613724565b5b8235905067ffffffffffffffff81111561376657613765613729565b5b6020830191508360018202830111156137825761378161372e565b5b9250929050565b60007fffffffffffffff0000000000000000000000000000000000000000000000000082169050919050565b6137be81613789565b81146137c957600080fd5b50565b6000813590506137db816137b5565b92915050565b6000806000604084860312156137fa576137f9613402565b5b600084013567ffffffffffffffff81111561381857613817613407565b5b61382486828701613733565b93509350506020613837868287016137cc565b9150509250925092565b60006020828403121561385757613856613402565b5b6000613865848285016137cc565b91505092915050565b600060ff82169050919050565b6138848161386e565b82525050565b610180820160008201516138a1600085018261387b565b5060208201516138b4602085018261387b565b5060408201516138c7604085018261387b565b5060608201516138da606085018261387b565b5060808201516138ed608085018261387b565b5060a082015161390060a085018261387b565b5060c082015161391360c085018261387b565b5060e082015161392660e085018261387b565b5061010082015161393b61010085018261387b565b5061012082015161395061012085018261387b565b5061014082015161396561014085018261387b565b5061016082015161397a61016085018261387b565b50505050565b600061018082019050613996600083018461388a565b92915050565b60008083601f8401126139b2576139b1613724565b5b8235905067ffffffffffffffff8111156139cf576139ce613729565b5b6020830191508360208202830111156139eb576139ea61372e565b5b9250929050565b60008083601f840112613a0857613a07613724565b5b8235905067ffffffffffffffff811115613a2557613a24613729565b5b602083019150836020820283011115613a4157613a4061372e565b5b9250929050565b60008060008060408587031215613a6257613a61613402565b5b600085013567ffffffffffffffff811115613a8057613a7f613407565b5b613a8c8782880161399c565b9450945050602085013567ffffffffffffffff811115613aaf57613aae613407565b5b613abb878288016139f2565b925092505092959194509250565b613ad281613604565b82525050565b6000602082019050613aed6000830184613ac9565b92915050565b600080600080600060608688031215613b0f57613b0e613402565b5b600086013567ffffffffffffffff811115613b2d57613b2c613407565b5b613b398882890161399c565b9550955050602086013567ffffffffffffffff811115613b5c57613b5b613407565b5b613b68888289016139f2565b93509350506040613b7b88828901613625565b9150509295509295909350565b613b9181613491565b8114613b9c57600080fd5b50565b600081359050613bae81613b88565b92915050565b60008060408385031215613bcb57613bca613402565b5b6000613bd985828601613510565b9250506020613bea85828601613b9f565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613c3182613598565b810181811067ffffffffffffffff82111715613c5057613c4f613bf9565b5b80604052505050565b6000613c636133f8565b9050613c6f8282613c28565b919050565b600067ffffffffffffffff821115613c8f57613c8e613bf9565b5b613c9882613598565b9050602081019050919050565b82818337600083830152505050565b6000613cc7613cc284613c74565b613c59565b905082815260208101848484011115613ce357613ce2613bf4565b5b613cee848285613ca5565b509392505050565b600082601f830112613d0b57613d0a613724565b5b8135613d1b848260208601613cb4565b91505092915050565b60008060008060808587031215613d3e57613d3d613402565b5b6000613d4c87828801613510565b9450506020613d5d87828801613510565b9350506040613d6e87828801613625565b925050606085013567ffffffffffffffff811115613d8f57613d8e613407565b5b613d9b87828801613cf6565b91505092959194509250565b60008060408385031215613dbe57613dbd613402565b5b6000613dcc85828601613510565b9250506020613ddd85828601613510565b9150509250929050565b600067ffffffffffffffff821115613e0257613e01613bf9565b5b602082029050602081019050919050565b6000613e26613e2184613de7565b613c59565b90508083825260208201905060208402830185811115613e4957613e4861372e565b5b835b81811015613e725780613e5e88826137cc565b845260208401935050602081019050613e4b565b5050509392505050565b600082601f830112613e9157613e90613724565b5b8135613ea1848260208601613e13565b91505092915050565b600060208284031215613ec057613ebf613402565b5b600082013567ffffffffffffffff811115613ede57613edd613407565b5b613eea84828501613e7c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613f3a57607f821691505b602082108103613f4d57613f4c613ef3565b5b50919050565b6000606082019050613f686000830186613667565b613f756020830185613ac9565b613f826040830184613667565b949350505050565b600080fd5b600080fd5b600067ffffffffffffffff821115613faf57613fae613bf9565b5b602082029050602081019050919050565b600067ffffffffffffffff821115613fdb57613fda613bf9565b5b613fe482613598565b9050602081019050919050565b6000614004613fff84613fc0565b613c59565b9050828152602081018484840111156140205761401f613bf4565b5b61402b84828561356e565b509392505050565b600082601f83011261404857614047613724565b5b8151614058848260208601613ff1565b91505092915050565b600061407461406f84613f94565b613c59565b905080838252602082019050602084028301858111156140975761409661372e565b5b835b818110156140de57805167ffffffffffffffff8111156140bc576140bb613724565b5b8086016140c98982614033565b85526020850194505050602081019050614099565b5050509392505050565b600082601f8301126140fd576140fc613724565b5b815161410d848260208601614061565b91505092915050565b6000610140828403121561412d5761412c613f8a565b5b614138610140613c59565b9050600082015167ffffffffffffffff81111561415857614157613f8f565b5b614164848285016140e8565b600083015250602082015167ffffffffffffffff81111561418857614187613f8f565b5b614194848285016140e8565b602083015250604082015167ffffffffffffffff8111156141b8576141b7613f8f565b5b6141c4848285016140e8565b604083015250606082015167ffffffffffffffff8111156141e8576141e7613f8f565b5b6141f4848285016140e8565b606083015250608082015167ffffffffffffffff81111561421857614217613f8f565b5b614224848285016140e8565b60808301525060a082015167ffffffffffffffff81111561424857614247613f8f565b5b614254848285016140e8565b60a08301525060c082015167ffffffffffffffff81111561427857614277613f8f565b5b614284848285016140e8565b60c08301525060e082015167ffffffffffffffff8111156142a8576142a7613f8f565b5b6142b4848285016140e8565b60e08301525061010082015167ffffffffffffffff8111156142d9576142d8613f8f565b5b6142e5848285016140e8565b6101008301525061012082015167ffffffffffffffff81111561430b5761430a613f8f565b5b614317848285016140e8565b6101208301525092915050565b60006020828403121561433a57614339613402565b5b600082015167ffffffffffffffff81111561435857614357613407565b5b61436484828501614116565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126143c8576143c761439c565b5b80840192508235915067ffffffffffffffff8211156143ea576143e96143a1565b5b602083019250600182023603831315614406576144056143a6565b5b509250929050565b60006fffffffffffffffffffffffffffffffff82169050919050565b6144338161440e565b811461443e57600080fd5b50565b6000813590506144508161442a565b92915050565b60006020828403121561446c5761446b613402565b5b600061447a84828501614441565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006144bd82613604565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144ef576144ee614483565b5b600182019050919050565b600061450582613604565b915061451083613604565b925082820390508181111561452857614527614483565b5b92915050565b600061453982613604565b915061454483613604565b925082820190508082111561455c5761455b614483565b5b92915050565b61456b8161386e565b82525050565b60006020820190506145866000830184614562565b92915050565b600081519050919050565b600082825260208201905092915050565b60006145b38261458c565b6145bd8185614597565b93506145cd81856020860161356e565b6145d681613598565b840191505092915050565b6000819050919050565b60006146066146016145fc8461440e565b6145e1565b613604565b9050919050565b614616816145eb565b82525050565b6000604082019050818103600083015261463681856145a8565b9050614645602083018461460d565b9392505050565b600061465f61465a84613c74565b613c59565b90508281526020810184848401111561467b5761467a613bf4565b5b61468684828561356e565b509392505050565b600082601f8301126146a3576146a2613724565b5b81516146b384826020860161464c565b91505092915050565b6000602082840312156146d2576146d1613402565b5b600082015167ffffffffffffffff8111156146f0576146ef613407565b5b6146fc8482850161468e565b91505092915050565b600060a0828403121561471b5761471a613f8a565b5b61472560a0613c59565b9050600082015167ffffffffffffffff81111561474557614744613f8f565b5b61475184828501614033565b600083015250602082015167ffffffffffffffff81111561477557614774613f8f565b5b61478184828501614033565b602083015250604082015167ffffffffffffffff8111156147a5576147a4613f8f565b5b6147b184828501614033565b604083015250606082015167ffffffffffffffff8111156147d5576147d4613f8f565b5b6147e184828501614033565b606083015250608082015167ffffffffffffffff81111561480557614804613f8f565b5b61481184828501614033565b60808301525092915050565b60006020828403121561483357614832613402565b5b600082015167ffffffffffffffff81111561485157614850613407565b5b61485d84828501614705565b91505092915050565b600061ffff82169050919050565b600061487f82614866565b915061488a83614866565b9250828201905061ffff8111156148a4576148a3614483565b5b92915050565b6148b381614866565b82525050565b60006020820190506148ce60008301846148aa565b92915050565b6000606082840312156148ea576148e9613f8a565b5b6148f46060613c59565b9050600082015167ffffffffffffffff81111561491457614913613f8f565b5b61492084828501614033565b600083015250602082015167ffffffffffffffff81111561494457614943613f8f565b5b61495084828501614033565b602083015250604082015167ffffffffffffffff81111561497457614973613f8f565b5b61498084828501614033565b60408301525092915050565b6000602082840312156149a2576149a1613402565b5b600082015167ffffffffffffffff8111156149c0576149bf613407565b5b6149cc848285016148d4565b91505092915050565b600081905092915050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000600082015250565b6000614a16601a836149d5565b9150614a21826149e0565b601a82019050919050565b6000614a3782613552565b614a4181856149d5565b9350614a5181856020860161356e565b80840191505092915050565b6000614a6882614a09565b9150614a748284614a2c565b915081905092915050565b7f7b00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614ab56001836149d5565b9150614ac082614a7f565b600182019050919050565b7f226e616d65223a202259616b79756b656e202300000000000000000000000000600082015250565b6000614b016013836149d5565b9150614b0c82614acb565b601382019050919050565b7f222c20226465736372697074696f6e223a202200000000000000000000000000600082015250565b6000614b4d6013836149d5565b9150614b5882614b17565b601382019050919050565b7f59616b79756b656e204e4654206f6e2d636861696e20636f6c6c656374696f6e60008201527f2e00000000000000000000000000000000000000000000000000000000000000602082015250565b6000614bbf6021836149d5565b9150614bca82614b63565b602182019050919050565b7f222c2022696d6167655f64617461223a20220000000000000000000000000000600082015250565b6000614c0b6012836149d5565b9150614c1682614bd5565b601282019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b6000614c576002836149d5565b9150614c6282614c21565b600282019050919050565b7f7d00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614ca36001836149d5565b9150614cae82614c6d565b600182019050919050565b6000614cc482614aa8565b9150614ccf82614af4565b9150614cdb8286614a2c565b9150614ce682614b40565b9150614cf182614bb2565b9150614cfc82614bfe565b9150614d088285614a2c565b9150614d1382614c4a565b9150614d1f8284614a2c565b9150614d2a82614c96565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000614d6d601d836149d5565b9150614d7882614d37565b601d82019050919050565b6000614d8e82614d60565b9150614d9a8284614a2c565b915081905092915050565b6000819050919050565b614db881614da5565b82525050565b6000602082019050614dd36000830184614daf565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614e1382613604565b9150614e1e83613604565b925082614e2e57614e2d614dd9565b5b828204905092915050565b6000614e4482613604565b9150614e4f83613604565b9250828202614e5d81613604565b91508282048414831517614e7457614e73614483565b5b5092915050565b600080fd5b600080fd5b60008085851115614e9957614e98614e7b565b5b83861115614eaa57614ea9614e80565b5b6001850283019150848603905094509492505050565b600081905092915050565b6000614ed68261458c565b614ee08185614ec0565b9350614ef081856020860161356e565b80840191505092915050565b6000614f088285614ecb565b9150614f148284614ecb565b91508190509392505050565b6000608082019050614f356000830187613667565b614f426020830186613667565b614f4f6040830185613ac9565b8181036060830152614f6181846145a8565b905095945050505050565b600081519050614f7b81613438565b92915050565b600060208284031215614f9757614f96613402565b5b6000614fa584828501614f6c565b91505092915050565b7f3c2f7376673e0000000000000000000000000000000000000000000000000000600082015250565b6000614fe46006836149d5565b9150614fef82614fae565b600682019050919050565b60006150068287614ecb565b91506150128286614ecb565b915061501e8285614a2c565b915061502a8284614ecb565b915061503582614fd7565b915081905095945050505050565b7f20226174747269627574657322203a205b7b202274726169745f74797065223a60008201527f2022436861726163746572222c202276616c7565223a22000000000000000000602082015250565b600061509f6037836149d5565b91506150aa82615043565b603782019050919050565b7f22207d2c20207b202274726169745f74797065223a202249636f6e222c20227660008201527f616c7565223a2022000000000000000000000000000000000000000000000000602082015250565b60006151116028836149d5565b915061511c826150b5565b602882019050919050565b7f227d2c20207b202274726169745f74797065223a20224261636b67726f756e6460008201527f20436f6c6f72222c202276616c7565223a202200000000000000000000000000602082015250565b60006151836033836149d5565b915061518e82615127565b603382019050919050565b7f22207d2c207b202274726169745f74797065223a2022496e697469616c20536860008201527f61646f7720436f6c6f72222c202276616c7565223a2200000000000000000000602082015250565b60006151f56036836149d5565b915061520082615199565b603682019050919050565b7f22207d2c207b202274726169745f74797065223a2022496e697469616c20536860008201527f61646f77204272696768746e657373222c202276616c7565223a220000000000602082015250565b6000615267603b836149d5565b91506152728261520b565b603b82019050919050565b7f22207d2c207b202274726169745f74797065223a202246696e616c205368616460008201527f6f7720436f6c6f7220222c202276616c7565223a220000000000000000000000602082015250565b60006152d96035836149d5565b91506152e48261527d565b603582019050919050565b7f22207d2c207b202274726169745f74797065223a202246696e616c205368616460008201527f6f77204272696768746e657373222c202276616c7565223a2200000000000000602082015250565b600061534b6039836149d5565b9150615356826152ef565b603982019050919050565b7f22207d2c207b202274726169745f74797065223a2022426173652046696c6c2060008201527f436f6c6f7273222c202276616c7565223a220000000000000000000000000000602082015250565b60006153bd6032836149d5565b91506153c882615361565b603282019050919050565b7f22207d2c207b202274726169745f74797065223a2022476c6f772054696d657360008201527f222c202276616c7565223a220000000000000000000000000000000000000000602082015250565b600061542f602c836149d5565b915061543a826153d3565b602c82019050919050565b7f22207d2c207b202274726169745f74797065223a202259616b2046696c6c204360008201527f6f6c6f7273222c202276616c7565223a22000000000000000000000000000000602082015250565b60006154a16031836149d5565b91506154ac82615445565b603182019050919050565b7f22207d2c207b202274726169745f74797065223a2022486f76657220436f6c6f60008201527f7273222c202276616c7565223a22000000000000000000000000000000000000602082015250565b6000615513602e836149d5565b915061551e826154b7565b602e82019050919050565b7f22207d2c207b202274726169745f74797065223a2022526f636b2c205061706560008201527f722c2053636973736f7273222c202276616c7565223a22000000000000000000602082015250565b60006155856037836149d5565b915061559082615529565b603782019050919050565b7f227d205d00000000000000000000000000000000000000000000000000000000600082015250565b60006155d16004836149d5565b91506155dc8261559b565b600482019050919050565b60006155f282615092565b91506155fe828f614a2c565b915061560982615104565b9150615615828e614a2c565b915061562082615176565b915061562c828d614a2c565b9150615637826151e8565b9150615643828c614a2c565b915061564e8261525a565b915061565a828b614a2c565b9150615665826152cc565b9150615671828a614a2c565b915061567c8261533e565b91506156888289614a2c565b9150615693826153b0565b915061569f8288614a2c565b91506156aa82615422565b91506156b68287614a2c565b91506156c182615494565b91506156cd8286614a2c565b91506156d882615506565b91506156e48285614a2c565b91506156ef82615578565b91506156fb8284614a2c565b9150615706826155c4565b91508190509d9c50505050505050505050505050565b60006040820190506157316000830185613667565b61573e6020830184613ac9565b9392505050565b60008082015250565b600061575b6001836149d5565b915061576682615745565b600182019050919050565b600061577c8261574e565b91506157888284614ecb565b915081905092915050565b7f600b5981380380925939f3000000000000000000000000000000000000000000600082015250565b60006157c9600b836149d5565b91506157d482615793565b600b82019050919050565b60006157ea826157bc565b91506157f68284614ecb565b915081905092915050565b7f4445504c4f594d454e545f4641494c4544000000000000000000000000000000600082015250565b600061583760118361355d565b915061584282615801565b602082019050919050565b600060208201905081810360008301526158668161582a565b9050919050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323060008201527f30302f73766722207072657365727665417370656374526174696f3d22784d6960208201527f64594d6964206d656574222076696577426f783d220000000000000000000000604082015250565b60006158ef6055836149d5565b91506158fa8261586d565b605582019050919050565b7f22207374796c653d226261636b67726f756e642d636f6c6f723a000000000000600082015250565b600061593b601a836149d5565b915061594682615905565b601a82019050919050565b7f223e000000000000000000000000000000000000000000000000000000000000600082015250565b60006159876002836149d5565b915061599282615951565b600282019050919050565b60006159a8826158e2565b91506159b48285614a2c565b91506159bf8261592e565b91506159cb8284614a2c565b91506159d68261597a565b91508190509392505050565b7f3c7374796c653e00000000000000000000000000000000000000000000000000600082015250565b6000615a186007836149d5565b9150615a23826159e2565b600782019050919050565b7f406b65796672616d657320676c6f77207b3025207b66696c7465723a2064726f60008201527f702d736861646f77283136707820313670782032307078200000000000000000602082015250565b6000615a8a6038836149d5565b9150615a9582615a2e565b603882019050919050565b7f29206272696768746e6573732800000000000000000000000000000000000000600082015250565b6000615ad6600d836149d5565b9150615ae182615aa0565b600d82019050919050565b7f25293b7d746f207b66696c7465723a2064726f702d736861646f77283136707860008201527f2031367078203230707820000000000000000000000000000000000000000000602082015250565b6000615b48602b836149d5565b9150615b5382615aec565b602b82019050919050565b7f25293b7d7d70617468207b66696c6c3a20000000000000000000000000000000600082015250565b6000615b946011836149d5565b9150615b9f82615b5e565b601182019050919050565b7f3b616e696d6174696f6e3a20676c6f7720000000000000000000000000000000600082015250565b6000615be06011836149d5565b9150615beb82615baa565b601182019050919050565b7f7320656173652d696e2d6f757420696e66696e69746520616c7465726e61746560008201527f3b7d2e79616b207b66696c6c3a20000000000000000000000000000000000000602082015250565b6000615c52602e836149d5565b9150615c5d82615bf6565b602e82019050919050565b7f3b7d2e79616b3a686f766572207b66696c6c3a20000000000000000000000000600082015250565b6000615c9e6014836149d5565b9150615ca982615c68565b601482019050919050565b7f3b7d2e69636f6e207b66696c6c3a200000000000000000000000000000000000600082015250565b6000615cea600f836149d5565b9150615cf582615cb4565b600f82019050919050565b7f3b7d3c2f7374796c653e00000000000000000000000000000000000000000000600082015250565b6000615d36600a836149d5565b9150615d4182615d00565b600a82019050919050565b6000615d5782615a0b565b9150615d6282615a7d565b9150615d6e828c614a2c565b9150615d7982615ac9565b9150615d85828b614a2c565b9150615d9082615b3b565b9150615d9c828a614a2c565b9150615da782615ac9565b9150615db38289614a2c565b9150615dbe82615b87565b9150615dca8288614a2c565b9150615dd582615bd3565b9150615de18287614a2c565b9150615dec82615c45565b9150615df88286614a2c565b9150615e0382615c91565b9150615e0f8285614a2c565b9150615e1a82615cdd565b9150615e268284614a2c565b9150615e3182615d29565b91508190509a9950505050505050505050565b7f3c73766720000000000000000000000000000000000000000000000000000000600082015250565b6000615e7a6005836149d5565b9150615e8582615e44565b600582019050919050565b7f3e20000000000000000000000000000000000000000000000000000000000000600082015250565b6000615ec66002836149d5565b9150615ed182615e90565b600282019050919050565b6000615ee782615e6d565b9150615ef38286614a2c565b9150615eff8285614a2c565b9150615f0a82615eb9565b9150615f168284614a2c565b9150615f2182614fd7565b915081905094935050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf42a4257216fe1e7138d6bf64f60b7b53428b0b904e3574c22dada2253a66b764736f6c6343000814003300000000000000000000000017a166d08ee8b2a7b3bd056d22eb5300b3652f49
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101735760003560e01c806370a08231116100de578063b88d4fde11610097578063efde823711610071578063efde823714610444578063efeee06d14610460578063f2fde38b14610490578063fea7dec7146104ac57610173565b8063b88d4fde146103c8578063c87b56dd146103e4578063e985e9c51461041457610173565b806370a082311461031a578063715018a61461034a5780637dcd47e0146103545780638da5cb5b1461037057806395d89b411461038e578063a22cb465146103ac57610173565b80633393450b116101305780633393450b1461024a5780633f5f96c01461026657806340c10f191461029657806342842e0e146102b257806352956954146102ce5780636352211e146102ea57610173565b806301ffc9a7146101785780630593d244146101a857806306fdde03146101c4578063081812fc146101e2578063095ea7b31461021257806323b872dd1461022e575b600080fd5b610192600480360381019061018d9190613464565b6104c8565b60405161019f91906134ac565b60405180910390f35b6101c260048036038101906101bd9190613525565b610529565b005b6101cc610575565b6040516101d991906135e2565b60405180910390f35b6101fc60048036038101906101f7919061363a565b610607565b6040516102099190613676565b60405180910390f35b61022c60048036038101906102279190613691565b610623565b005b610248600480360381019061024391906136d1565b610639565b005b610264600480360381019061025f91906137e1565b61073b565b005b610280600480360381019061027b9190613841565b6107a0565b60405161028d9190613980565b60405180910390f35b6102b060048036038101906102ab9190613691565b6109a2565b005b6102cc60048036038101906102c791906136d1565b610a37565b005b6102e860048036038101906102e39190613a48565b610a57565b005b61030460048036038101906102ff919061363a565b610b7a565b6040516103119190613676565b60405180910390f35b610334600480360381019061032f9190613525565b610b8c565b6040516103419190613ad8565b60405180910390f35b610352610c46565b005b61036e60048036038101906103699190613af3565b610c5a565b005b610378610d97565b6040516103859190613676565b60405180910390f35b610396610dc1565b6040516103a391906135e2565b60405180910390f35b6103c660048036038101906103c19190613bb4565b610e53565b005b6103e260048036038101906103dd9190613d24565b610e69565b005b6103fe60048036038101906103f9919061363a565b610e86565b60405161040b91906135e2565b60405180910390f35b61042e60048036038101906104299190613da7565b61126d565b60405161043b91906134ac565b60405180910390f35b61045e60048036038101906104599190613a48565b611301565b005b61047a6004803603810190610475919061363a565b611434565b60405161048791906135e2565b60405180910390f35b6104aa60048036038101906104a59190613525565b611776565b005b6104c660048036038101906104c19190613eaa565b6117fc565b005b6000634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061052257506105218261181e565b5b9050919050565b610531611900565b80600e60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60606001805461058490613f22565b80601f01602080910402602001604051908101604052809291908181526020018280546105b090613f22565b80156105fd5780601f106105d2576101008083540402835291602001916105fd565b820191906000526020600020905b8154815290600101906020018083116105e057829003601f168201915b5050505050905090565b600061061282611987565b5061061c82611a0f565b9050919050565b6106358282610630611a4c565b611a54565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036106ab5760006040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016106a29190613676565b60405180910390fd5b60006106bf83836106ba611a4c565b611a66565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610735578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161072c93929190613f53565b60405180910390fd5b50505050565b610743611900565b600061074e81611c80565b6107797f7a9d3a032b8ff274f09714b56ba8e5ed776ec9638ca303069bc3a3267bb22f658585611d19565b81600c60006101000a81548166ffffffffffffff021916908360c81c021790555050505050565b6107a86132a3565b60006107d37f7a9d3a032b8ff274f09714b56ba8e5ed776ec9638ca303069bc3a3267bb22f65611edb565b8060200190518101906107e69190614324565b90506107fa83600080846080015151611f96565b826000019060ff16908160ff168152505061081e8360016000846000015151611f96565b826020019060ff16908160ff1681525050610843836002600484610120015151611f96565b826040019060ff16908160ff1681525050610867836002600a846060015151611f96565b826060019060ff16908160ff168152505061088b8360036004846020015151611f96565b826080019060ff16908160ff16815250506108b0836003600a84610100015151611f96565b8260a0019060ff16908160ff16815250506108d383600480600980549050611f96565b8260c0019060ff16908160ff16815250506108f7836004600a8460c0015151611f96565b8260e0019060ff16908160ff168152505061091b83600560048460a0015151611f96565b82610100019060ff16908160ff1681525050610940836005600a846040015151611f96565b82610120019060ff16908160ff16815250506109658360066004600a80549050611f96565b82610140019060ff16908160ff168152505061098a836006600a8460e0015151611f96565b82610160019060ff16908160ff168152505050919050565b600e60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a29576040517f179b043d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a338282612086565b5050565b610a5283838360405180602001604052806000815250610e69565b505050565b610a5f611900565b6001610a6a81611c80565b600085859050905060005b81811015610b7157610ad181604051602001610a919190613ad8565b60405160208183030381529060405280519060200120888884818110610aba57610ab961436d565b5b9050602002810190610acc91906143ab565b611d19565b6009858583818110610ae657610ae561436d565b5b9050602002016020810190610afb9190614456565b90806001815401808255809150506001900390600052602060002090600291828204019190066010029091909190916101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508080610b69906144b2565b915050610a75565b50505050505050565b6000610b8582611987565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610bff5760006040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401610bf69190613676565b60405180910390fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610c4e611900565b610c58600061217f565b565b610c62611900565b6002610c6d81611c80565b60008686905083610c7e91906144fa565b905060005b87879050811015610d8d57610ced8282610c9d919061452e565b604051602001610cad9190613ad8565b60405160208183030381529060405280519060200120898984818110610cd657610cd561436d565b5b9050602002810190610ce891906143ab565b611d19565b6009868683818110610d0257610d0161436d565b5b9050602002016020810190610d179190614456565b90806001815401808255809150506001900390600052602060002090600291828204019190066010029091909190916101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508080610d85906144b2565b915050610c83565b5050505050505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060028054610dd090613f22565b80601f0160208091040260200160405190810160405280929190818152602001828054610dfc90613f22565b8015610e495780601f10610e1e57610100808354040283529160200191610e49565b820191906000526020600020905b815481529060010190602001808311610e2c57829003601f168201915b5050505050905090565b610e65610e5e611a4c565b8383612245565b5050565b610e74848484610639565b610e80848484846123b4565b50505050565b6060610e906132a3565b610ef26000600b8054905011610eb557600c60009054906101000a900460c81b610eed565b600b8481548110610ec957610ec861436d565b5b90600052602060002090600491828204019190066007029054906101000a900460c81b5b6107a0565b90506000610f1f7f7a9d3a032b8ff274f09714b56ba8e5ed776ec9638ca303069bc3a3267bb22f65611edb565b806020019051810190610f329190614324565b905060007f00000000000000000000000017a166d08ee8b2a7b3bd056d22eb5300b3652f4973ffffffffffffffffffffffffffffffffffffffff16637b631b69610fa58560c00151604051602001610f8a9190614571565b60405160208183030381529060405280519060200120611edb565b60098660c0015160ff1681548110610fc057610fbf61436d565b5b90600052602060002090600291828204019190066010029054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161100f92919061461c565b600060405180830381865afa15801561102c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061105591906146bc565b806020019051810190611068919061481d565b905060007f00000000000000000000000017a166d08ee8b2a7b3bd056d22eb5300b3652f4973ffffffffffffffffffffffffffffffffffffffff16637b631b696110eb606487610140015160ff166110c09190614874565b6040516020016110d091906148b9565b60405160208183030381529060405280519060200120611edb565b600a87610140015160ff16815481106111075761110661436d565b5b90600052602060002090600291828204019190066010029054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161115692919061461c565b600060405180830381865afa158015611173573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061119c91906146bc565b8060200190518101906111af919061498c565b905060006111bc8761256b565b6111d06111cb87878787612639565b612814565b6040516020016111e09190614a5d565b60405160208183030381529060405261121687876040518060400160405280896080015181526020018860200151815250612977565b60405160200161122893929190614cb9565b604051602081830303815290604052905061124281612814565b6040516020016112529190614d83565b60405160208183030381529060405295505050505050919050565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611309611900565b600361131481611c80565b600085859050905060005b8181101561142b5761138b606461ffff168261133b919061452e565b60405160200161134b9190613ad8565b604051602081830303815290604052805190602001208888848181106113745761137361436d565b5b905060200281019061138691906143ab565b611d19565b600a8585838181106113a05761139f61436d565b5b90506020020160208101906113b59190614456565b90806001815401808255809150506001900390600052602060002090600291828204019190066010029091909190916101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055508080611423906144b2565b91505061131f565b50505050505050565b606061143e6132a3565b6114a06000600b805490501161146357600c60009054906101000a900460c81b61149b565b600b84815481106114775761147661436d565b5b90600052602060002090600491828204019190066007029054906101000a900460c81b5b6107a0565b905060006114cd7f7a9d3a032b8ff274f09714b56ba8e5ed776ec9638ca303069bc3a3267bb22f65611edb565b8060200190518101906114e09190614324565b905060007f00000000000000000000000017a166d08ee8b2a7b3bd056d22eb5300b3652f4973ffffffffffffffffffffffffffffffffffffffff16637b631b696115538560c001516040516020016115389190614571565b60405160208183030381529060405280519060200120611edb565b60098660c0015160ff168154811061156e5761156d61436d565b5b90600052602060002090600291828204019190066010029054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b81526004016115bd92919061461c565b600060405180830381865afa1580156115da573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061160391906146bc565b806020019051810190611616919061481d565b905060007f00000000000000000000000017a166d08ee8b2a7b3bd056d22eb5300b3652f4973ffffffffffffffffffffffffffffffffffffffff16637b631b69611699606487610140015160ff1661166e9190614874565b60405160200161167e91906148b9565b60405160208183030381529060405280519060200120611edb565b600a87610140015160ff16815481106116b5576116b461436d565b5b90600052602060002090600291828204019190066010029054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161170492919061461c565b600060405180830381865afa158015611721573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061174a91906146bc565b80602001905181019061175d919061498c565b905061176b84848484612639565b945050505050919050565b61177e611900565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036117f05760006040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016117e79190613676565b60405180910390fd5b6117f98161217f565b50565b611804611900565b80600b908051906020019061181a929190613328565b5050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806118e957507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806118f957506118f882612b5f565b5b9050919050565b611908611a4c565b73ffffffffffffffffffffffffffffffffffffffff16611926610d97565b73ffffffffffffffffffffffffffffffffffffffff161461198557611949611a4c565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161197c9190613676565b60405180910390fd5b565b60008061199383612bc9565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a0657826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016119fd9190613ad8565b60405180910390fd5b80915050919050565b60006005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600033905090565b611a618383836001612c06565b505050565b600080611a7284612bc9565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614611ab457611ab3818486612dcb565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611b4557611af6600085600080612c06565b6001600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614611bc8576001600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846003600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b600d8160048110611c9457611c9361436d565b5b602091828204019190069054906101000a900460ff1615611ce1576040517f2e60c66000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600d8260048110611cf757611cf661436d565b5b602091828204019190066101000a81548160ff02191690831515021790555050565b60008060008581526020019081526020016000208054905014611d7357826040517f39474a48000000000000000000000000000000000000000000000000000000008152600401611d6a9190614dbe565b60405180910390fd5b600082829050905060006001615fff83611d8d9190614e08565b611d97919061452e565b905060005b81811015611ed357600080878152602001908152602001600020611e608686615fff85611dc99190614e39565b90615fff600187611dda919061452e565b611de49190614e39565b8811611df05787611e0b565b615fff600187611e00919061452e565b611e0a9190614e39565b5b92611e1893929190614e85565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612e8f565b9080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508080611ecb906144b2565b915050611d9c565b505050505050565b6060600080600084815260200190815260200160002080549050905060005b81811015611f8f5782611f5a6000808781526020019081526020016000208381548110611f2a57611f2961436d565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612f59565b604051602001611f6b929190614efc565b60405160208183030381529060405292508080611f87906144b2565b915050611efa565b5050919050565b6000808360ff1603611fc657848460ff1660078110611fb857611fb761436d565b5b1a60f81b60f81c9050612042565b60048360ff160361201b576004858560ff1660078110611fe957611fe861436d565b5b1a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60f81c9050612041565b600f60f81b858560ff16600781106120365761203561436d565b5b1a60f81b1660f81c90505b5b818160ff161061207e576040517f32064cab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036120f85760006040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016120ef9190613676565b60405180910390fd5b600061210683836000611a66565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461217a5760006040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016121719190613676565b60405180910390fd5b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036122b657816040517f5b08ba180000000000000000000000000000000000000000000000000000000081526004016122ad9190613676565b60405180910390fd5b80600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516123a791906134ac565b60405180910390a3505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b1115612565578273ffffffffffffffffffffffffffffffffffffffff1663150b7a026123f8611a4c565b8685856040518563ffffffff1660e01b815260040161241a9493929190614f20565b6020604051808303816000875af192505050801561245657506040513d601f19601f820116820180604052508101906124539190614f81565b60015b6124da573d8060008114612486576040519150601f19603f3d011682016040523d82523d6000602084013e61248b565b606091505b5060008151036124d257836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016124c99190613676565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461256357836040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161255a9190613676565b60405180910390fd5b505b50505050565b60606000600161257a84612f90565b01905060008167ffffffffffffffff81111561259957612598613bf9565b5b6040519080825280601f01601f1916602001820160405280156125cb5781602001600182028036833780820191505090505b509050600082602001820190505b60011561262e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161262257612621614dd9565b5b049450600085036125d9575b819350505050919050565b606061266e83602001518560000151876020015160ff16815181106126615761266061436d565b5b60200260200101516130e3565b6127d18560c001518760e0015160ff168151811061268f5761268e61436d565b5b60200260200101518660600151886060015160ff16815181106126b5576126b461436d565b5b60200260200101518760a0015189610100015160ff16815181106126dc576126db61436d565b5b602002602001015188604001518a610120015160ff16815181106127035761270261436d565b5b602002602001015189602001518b6080015160ff16815181106127295761272861436d565b5b60200260200101518a608001518c6000015160ff168151811061274f5761274e61436d565b5b60200260200101518b61010001518d60a0015160ff16815181106127765761277561436d565b5b60200260200101518c61012001518e6040015160ff168151811061279d5761279c61436d565b5b60200260200101518d61010001518f60a0015160ff16815181106127c4576127c361436d565b5b602002602001015161310f565b84600001516127e885604001518760600151613150565b6040516020016127fb9493929190614ffa565b6040516020818303038152906040529050949350505050565b6060600082510361283657604051806020016040528060008152509050612972565b6000604051806060016040528060408152602001615f2f6040913990506000600360028551612865919061452e565b61286f9190614e08565b600461287b9190614e39565b67ffffffffffffffff81111561289457612893613bf9565b5b6040519080825280601f01601f1916602001820160405280156128c65781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015612932576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453600184019350506128d7565b505060038651066001811461294e576002811461296157612969565b603d6001830353603d6002830353612969565b603d60018303535b50505080925050505b919050565b60608160006002811061298d5761298c61436d565b5b6020020151826001600281106129a6576129a561436d565b5b60200201518460000151866020015160ff16815181106129c9576129c861436d565b5b60200260200101518560c001518760e0015160ff16815181106129ef576129ee61436d565b5b60200260200101518660a0015188610100015160ff1681518110612a1657612a1561436d565b5b60200260200101518760600151896060015160ff1681518110612a3c57612a3b61436d565b5b602002602001015188604001518a610120015160ff1681518110612a6357612a6261436d565b5b602002602001015189602001518b6080015160ff1681518110612a8957612a8861436d565b5b60200260200101518a608001518c6000015160ff1681518110612aaf57612aae61436d565b5b60200260200101518b61010001518d60a0015160ff1681518110612ad657612ad561436d565b5b60200260200101518c61012001518e6040015160ff1681518110612afd57612afc61436d565b5b60200260200101518d60e001518f610160015160ff1681518110612b2457612b2361436d565b5b6020026020010151604051602001612b479c9b9a999897969594939291906155e7565b60405160208183030381529060405290509392505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60006003600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8080612c3f5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b15612d73576000612c4f84611987565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015612cba57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015612ccd5750612ccb818461126d565b155b15612d0f57826040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401612d069190613676565b60405180910390fd5b8115612d7157838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836005600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b612dd68383836131b9565b612e8a57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612e4b57806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401612e429190613ad8565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401612e8192919061571c565b60405180910390fd5b505050565b60008082604051602001612ea39190615771565b6040516020818303038152906040529050600081604051602001612ec791906157df565b60405160208183030381529060405290508051602082016000f09250600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612f52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f499061584d565b60405180910390fd5b5050919050565b6060612f89826001808573ffffffffffffffffffffffffffffffffffffffff163b612f8491906144fa565b61327a565b9050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612fee577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612fe457612fe3614dd9565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061302b576d04ee2d6d415b85acef8100000000838161302157613020614dd9565b5b0492506020810190505b662386f26fc10000831061305a57662386f26fc1000083816130505761304f614dd9565b5b0492506010810190505b6305f5e1008310613083576305f5e100838161307957613078614dd9565b5b0492506008810190505b61271083106130a857612710838161309e5761309d614dd9565b5b0492506004810190505b606483106130cb57606483816130c1576130c0614dd9565b5b0492506002810190505b600a83106130da576001810190505b80915050919050565b606082826040516020016130f892919061599d565b604051602081830303815290604052905092915050565b606089888a89898989898960405160200161313299989796959493929190615d4c565b60405160208183030381529060405290509998505050505050505050565b606060006040518060400160405280600f81526020017f20783d2235252220793d2235252220000000000000000000000000000000000081525090508281856040516020016131a193929190615edc565b60405160208183030381529060405291505092915050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561327157508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806132325750613231848461126d565b5b8061327057508273ffffffffffffffffffffffffffffffffffffffff1661325883611a0f565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b60606040519050601f19601f6020840101168101604052818152818360208301863c9392505050565b604051806101800160405280600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff168152602001600060ff1681525090565b828054828255906000526020600020906003016004900481019282156133ca5791602002820160005b8382111561339557835183826101000a81548166ffffffffffffff021916908360c81c02179055509260200192600701602081600601049283019260010302613351565b80156133c85782816101000a81549066ffffffffffffff0219169055600701602081600601049283019260010302613395565b505b5090506133d791906133db565b5090565b5b808211156133f45760008160009055506001016133dc565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6134418161340c565b811461344c57600080fd5b50565b60008135905061345e81613438565b92915050565b60006020828403121561347a57613479613402565b5b60006134888482850161344f565b91505092915050565b60008115159050919050565b6134a681613491565b82525050565b60006020820190506134c1600083018461349d565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006134f2826134c7565b9050919050565b613502816134e7565b811461350d57600080fd5b50565b60008135905061351f816134f9565b92915050565b60006020828403121561353b5761353a613402565b5b600061354984828501613510565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561358c578082015181840152602081019050613571565b60008484015250505050565b6000601f19601f8301169050919050565b60006135b482613552565b6135be818561355d565b93506135ce81856020860161356e565b6135d781613598565b840191505092915050565b600060208201905081810360008301526135fc81846135a9565b905092915050565b6000819050919050565b61361781613604565b811461362257600080fd5b50565b6000813590506136348161360e565b92915050565b6000602082840312156136505761364f613402565b5b600061365e84828501613625565b91505092915050565b613670816134e7565b82525050565b600060208201905061368b6000830184613667565b92915050565b600080604083850312156136a8576136a7613402565b5b60006136b685828601613510565b92505060206136c785828601613625565b9150509250929050565b6000806000606084860312156136ea576136e9613402565b5b60006136f886828701613510565b935050602061370986828701613510565b925050604061371a86828701613625565b9150509250925092565b600080fd5b600080fd5b600080fd5b60008083601f84011261374957613748613724565b5b8235905067ffffffffffffffff81111561376657613765613729565b5b6020830191508360018202830111156137825761378161372e565b5b9250929050565b60007fffffffffffffff0000000000000000000000000000000000000000000000000082169050919050565b6137be81613789565b81146137c957600080fd5b50565b6000813590506137db816137b5565b92915050565b6000806000604084860312156137fa576137f9613402565b5b600084013567ffffffffffffffff81111561381857613817613407565b5b61382486828701613733565b93509350506020613837868287016137cc565b9150509250925092565b60006020828403121561385757613856613402565b5b6000613865848285016137cc565b91505092915050565b600060ff82169050919050565b6138848161386e565b82525050565b610180820160008201516138a1600085018261387b565b5060208201516138b4602085018261387b565b5060408201516138c7604085018261387b565b5060608201516138da606085018261387b565b5060808201516138ed608085018261387b565b5060a082015161390060a085018261387b565b5060c082015161391360c085018261387b565b5060e082015161392660e085018261387b565b5061010082015161393b61010085018261387b565b5061012082015161395061012085018261387b565b5061014082015161396561014085018261387b565b5061016082015161397a61016085018261387b565b50505050565b600061018082019050613996600083018461388a565b92915050565b60008083601f8401126139b2576139b1613724565b5b8235905067ffffffffffffffff8111156139cf576139ce613729565b5b6020830191508360208202830111156139eb576139ea61372e565b5b9250929050565b60008083601f840112613a0857613a07613724565b5b8235905067ffffffffffffffff811115613a2557613a24613729565b5b602083019150836020820283011115613a4157613a4061372e565b5b9250929050565b60008060008060408587031215613a6257613a61613402565b5b600085013567ffffffffffffffff811115613a8057613a7f613407565b5b613a8c8782880161399c565b9450945050602085013567ffffffffffffffff811115613aaf57613aae613407565b5b613abb878288016139f2565b925092505092959194509250565b613ad281613604565b82525050565b6000602082019050613aed6000830184613ac9565b92915050565b600080600080600060608688031215613b0f57613b0e613402565b5b600086013567ffffffffffffffff811115613b2d57613b2c613407565b5b613b398882890161399c565b9550955050602086013567ffffffffffffffff811115613b5c57613b5b613407565b5b613b68888289016139f2565b93509350506040613b7b88828901613625565b9150509295509295909350565b613b9181613491565b8114613b9c57600080fd5b50565b600081359050613bae81613b88565b92915050565b60008060408385031215613bcb57613bca613402565b5b6000613bd985828601613510565b9250506020613bea85828601613b9f565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613c3182613598565b810181811067ffffffffffffffff82111715613c5057613c4f613bf9565b5b80604052505050565b6000613c636133f8565b9050613c6f8282613c28565b919050565b600067ffffffffffffffff821115613c8f57613c8e613bf9565b5b613c9882613598565b9050602081019050919050565b82818337600083830152505050565b6000613cc7613cc284613c74565b613c59565b905082815260208101848484011115613ce357613ce2613bf4565b5b613cee848285613ca5565b509392505050565b600082601f830112613d0b57613d0a613724565b5b8135613d1b848260208601613cb4565b91505092915050565b60008060008060808587031215613d3e57613d3d613402565b5b6000613d4c87828801613510565b9450506020613d5d87828801613510565b9350506040613d6e87828801613625565b925050606085013567ffffffffffffffff811115613d8f57613d8e613407565b5b613d9b87828801613cf6565b91505092959194509250565b60008060408385031215613dbe57613dbd613402565b5b6000613dcc85828601613510565b9250506020613ddd85828601613510565b9150509250929050565b600067ffffffffffffffff821115613e0257613e01613bf9565b5b602082029050602081019050919050565b6000613e26613e2184613de7565b613c59565b90508083825260208201905060208402830185811115613e4957613e4861372e565b5b835b81811015613e725780613e5e88826137cc565b845260208401935050602081019050613e4b565b5050509392505050565b600082601f830112613e9157613e90613724565b5b8135613ea1848260208601613e13565b91505092915050565b600060208284031215613ec057613ebf613402565b5b600082013567ffffffffffffffff811115613ede57613edd613407565b5b613eea84828501613e7c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613f3a57607f821691505b602082108103613f4d57613f4c613ef3565b5b50919050565b6000606082019050613f686000830186613667565b613f756020830185613ac9565b613f826040830184613667565b949350505050565b600080fd5b600080fd5b600067ffffffffffffffff821115613faf57613fae613bf9565b5b602082029050602081019050919050565b600067ffffffffffffffff821115613fdb57613fda613bf9565b5b613fe482613598565b9050602081019050919050565b6000614004613fff84613fc0565b613c59565b9050828152602081018484840111156140205761401f613bf4565b5b61402b84828561356e565b509392505050565b600082601f83011261404857614047613724565b5b8151614058848260208601613ff1565b91505092915050565b600061407461406f84613f94565b613c59565b905080838252602082019050602084028301858111156140975761409661372e565b5b835b818110156140de57805167ffffffffffffffff8111156140bc576140bb613724565b5b8086016140c98982614033565b85526020850194505050602081019050614099565b5050509392505050565b600082601f8301126140fd576140fc613724565b5b815161410d848260208601614061565b91505092915050565b6000610140828403121561412d5761412c613f8a565b5b614138610140613c59565b9050600082015167ffffffffffffffff81111561415857614157613f8f565b5b614164848285016140e8565b600083015250602082015167ffffffffffffffff81111561418857614187613f8f565b5b614194848285016140e8565b602083015250604082015167ffffffffffffffff8111156141b8576141b7613f8f565b5b6141c4848285016140e8565b604083015250606082015167ffffffffffffffff8111156141e8576141e7613f8f565b5b6141f4848285016140e8565b606083015250608082015167ffffffffffffffff81111561421857614217613f8f565b5b614224848285016140e8565b60808301525060a082015167ffffffffffffffff81111561424857614247613f8f565b5b614254848285016140e8565b60a08301525060c082015167ffffffffffffffff81111561427857614277613f8f565b5b614284848285016140e8565b60c08301525060e082015167ffffffffffffffff8111156142a8576142a7613f8f565b5b6142b4848285016140e8565b60e08301525061010082015167ffffffffffffffff8111156142d9576142d8613f8f565b5b6142e5848285016140e8565b6101008301525061012082015167ffffffffffffffff81111561430b5761430a613f8f565b5b614317848285016140e8565b6101208301525092915050565b60006020828403121561433a57614339613402565b5b600082015167ffffffffffffffff81111561435857614357613407565b5b61436484828501614116565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b600080833560016020038436030381126143c8576143c761439c565b5b80840192508235915067ffffffffffffffff8211156143ea576143e96143a1565b5b602083019250600182023603831315614406576144056143a6565b5b509250929050565b60006fffffffffffffffffffffffffffffffff82169050919050565b6144338161440e565b811461443e57600080fd5b50565b6000813590506144508161442a565b92915050565b60006020828403121561446c5761446b613402565b5b600061447a84828501614441565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006144bd82613604565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144ef576144ee614483565b5b600182019050919050565b600061450582613604565b915061451083613604565b925082820390508181111561452857614527614483565b5b92915050565b600061453982613604565b915061454483613604565b925082820190508082111561455c5761455b614483565b5b92915050565b61456b8161386e565b82525050565b60006020820190506145866000830184614562565b92915050565b600081519050919050565b600082825260208201905092915050565b60006145b38261458c565b6145bd8185614597565b93506145cd81856020860161356e565b6145d681613598565b840191505092915050565b6000819050919050565b60006146066146016145fc8461440e565b6145e1565b613604565b9050919050565b614616816145eb565b82525050565b6000604082019050818103600083015261463681856145a8565b9050614645602083018461460d565b9392505050565b600061465f61465a84613c74565b613c59565b90508281526020810184848401111561467b5761467a613bf4565b5b61468684828561356e565b509392505050565b600082601f8301126146a3576146a2613724565b5b81516146b384826020860161464c565b91505092915050565b6000602082840312156146d2576146d1613402565b5b600082015167ffffffffffffffff8111156146f0576146ef613407565b5b6146fc8482850161468e565b91505092915050565b600060a0828403121561471b5761471a613f8a565b5b61472560a0613c59565b9050600082015167ffffffffffffffff81111561474557614744613f8f565b5b61475184828501614033565b600083015250602082015167ffffffffffffffff81111561477557614774613f8f565b5b61478184828501614033565b602083015250604082015167ffffffffffffffff8111156147a5576147a4613f8f565b5b6147b184828501614033565b604083015250606082015167ffffffffffffffff8111156147d5576147d4613f8f565b5b6147e184828501614033565b606083015250608082015167ffffffffffffffff81111561480557614804613f8f565b5b61481184828501614033565b60808301525092915050565b60006020828403121561483357614832613402565b5b600082015167ffffffffffffffff81111561485157614850613407565b5b61485d84828501614705565b91505092915050565b600061ffff82169050919050565b600061487f82614866565b915061488a83614866565b9250828201905061ffff8111156148a4576148a3614483565b5b92915050565b6148b381614866565b82525050565b60006020820190506148ce60008301846148aa565b92915050565b6000606082840312156148ea576148e9613f8a565b5b6148f46060613c59565b9050600082015167ffffffffffffffff81111561491457614913613f8f565b5b61492084828501614033565b600083015250602082015167ffffffffffffffff81111561494457614943613f8f565b5b61495084828501614033565b602083015250604082015167ffffffffffffffff81111561497457614973613f8f565b5b61498084828501614033565b60408301525092915050565b6000602082840312156149a2576149a1613402565b5b600082015167ffffffffffffffff8111156149c0576149bf613407565b5b6149cc848285016148d4565b91505092915050565b600081905092915050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000600082015250565b6000614a16601a836149d5565b9150614a21826149e0565b601a82019050919050565b6000614a3782613552565b614a4181856149d5565b9350614a5181856020860161356e565b80840191505092915050565b6000614a6882614a09565b9150614a748284614a2c565b915081905092915050565b7f7b00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614ab56001836149d5565b9150614ac082614a7f565b600182019050919050565b7f226e616d65223a202259616b79756b656e202300000000000000000000000000600082015250565b6000614b016013836149d5565b9150614b0c82614acb565b601382019050919050565b7f222c20226465736372697074696f6e223a202200000000000000000000000000600082015250565b6000614b4d6013836149d5565b9150614b5882614b17565b601382019050919050565b7f59616b79756b656e204e4654206f6e2d636861696e20636f6c6c656374696f6e60008201527f2e00000000000000000000000000000000000000000000000000000000000000602082015250565b6000614bbf6021836149d5565b9150614bca82614b63565b602182019050919050565b7f222c2022696d6167655f64617461223a20220000000000000000000000000000600082015250565b6000614c0b6012836149d5565b9150614c1682614bd5565b601282019050919050565b7f222c000000000000000000000000000000000000000000000000000000000000600082015250565b6000614c576002836149d5565b9150614c6282614c21565b600282019050919050565b7f7d00000000000000000000000000000000000000000000000000000000000000600082015250565b6000614ca36001836149d5565b9150614cae82614c6d565b600182019050919050565b6000614cc482614aa8565b9150614ccf82614af4565b9150614cdb8286614a2c565b9150614ce682614b40565b9150614cf182614bb2565b9150614cfc82614bfe565b9150614d088285614a2c565b9150614d1382614c4a565b9150614d1f8284614a2c565b9150614d2a82614c96565b9150819050949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000600082015250565b6000614d6d601d836149d5565b9150614d7882614d37565b601d82019050919050565b6000614d8e82614d60565b9150614d9a8284614a2c565b915081905092915050565b6000819050919050565b614db881614da5565b82525050565b6000602082019050614dd36000830184614daf565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614e1382613604565b9150614e1e83613604565b925082614e2e57614e2d614dd9565b5b828204905092915050565b6000614e4482613604565b9150614e4f83613604565b9250828202614e5d81613604565b91508282048414831517614e7457614e73614483565b5b5092915050565b600080fd5b600080fd5b60008085851115614e9957614e98614e7b565b5b83861115614eaa57614ea9614e80565b5b6001850283019150848603905094509492505050565b600081905092915050565b6000614ed68261458c565b614ee08185614ec0565b9350614ef081856020860161356e565b80840191505092915050565b6000614f088285614ecb565b9150614f148284614ecb565b91508190509392505050565b6000608082019050614f356000830187613667565b614f426020830186613667565b614f4f6040830185613ac9565b8181036060830152614f6181846145a8565b905095945050505050565b600081519050614f7b81613438565b92915050565b600060208284031215614f9757614f96613402565b5b6000614fa584828501614f6c565b91505092915050565b7f3c2f7376673e0000000000000000000000000000000000000000000000000000600082015250565b6000614fe46006836149d5565b9150614fef82614fae565b600682019050919050565b60006150068287614ecb565b91506150128286614ecb565b915061501e8285614a2c565b915061502a8284614ecb565b915061503582614fd7565b915081905095945050505050565b7f20226174747269627574657322203a205b7b202274726169745f74797065223a60008201527f2022436861726163746572222c202276616c7565223a22000000000000000000602082015250565b600061509f6037836149d5565b91506150aa82615043565b603782019050919050565b7f22207d2c20207b202274726169745f74797065223a202249636f6e222c20227660008201527f616c7565223a2022000000000000000000000000000000000000000000000000602082015250565b60006151116028836149d5565b915061511c826150b5565b602882019050919050565b7f227d2c20207b202274726169745f74797065223a20224261636b67726f756e6460008201527f20436f6c6f72222c202276616c7565223a202200000000000000000000000000602082015250565b60006151836033836149d5565b915061518e82615127565b603382019050919050565b7f22207d2c207b202274726169745f74797065223a2022496e697469616c20536860008201527f61646f7720436f6c6f72222c202276616c7565223a2200000000000000000000602082015250565b60006151f56036836149d5565b915061520082615199565b603682019050919050565b7f22207d2c207b202274726169745f74797065223a2022496e697469616c20536860008201527f61646f77204272696768746e657373222c202276616c7565223a220000000000602082015250565b6000615267603b836149d5565b91506152728261520b565b603b82019050919050565b7f22207d2c207b202274726169745f74797065223a202246696e616c205368616460008201527f6f7720436f6c6f7220222c202276616c7565223a220000000000000000000000602082015250565b60006152d96035836149d5565b91506152e48261527d565b603582019050919050565b7f22207d2c207b202274726169745f74797065223a202246696e616c205368616460008201527f6f77204272696768746e657373222c202276616c7565223a2200000000000000602082015250565b600061534b6039836149d5565b9150615356826152ef565b603982019050919050565b7f22207d2c207b202274726169745f74797065223a2022426173652046696c6c2060008201527f436f6c6f7273222c202276616c7565223a220000000000000000000000000000602082015250565b60006153bd6032836149d5565b91506153c882615361565b603282019050919050565b7f22207d2c207b202274726169745f74797065223a2022476c6f772054696d657360008201527f222c202276616c7565223a220000000000000000000000000000000000000000602082015250565b600061542f602c836149d5565b915061543a826153d3565b602c82019050919050565b7f22207d2c207b202274726169745f74797065223a202259616b2046696c6c204360008201527f6f6c6f7273222c202276616c7565223a22000000000000000000000000000000602082015250565b60006154a16031836149d5565b91506154ac82615445565b603182019050919050565b7f22207d2c207b202274726169745f74797065223a2022486f76657220436f6c6f60008201527f7273222c202276616c7565223a22000000000000000000000000000000000000602082015250565b6000615513602e836149d5565b915061551e826154b7565b602e82019050919050565b7f22207d2c207b202274726169745f74797065223a2022526f636b2c205061706560008201527f722c2053636973736f7273222c202276616c7565223a22000000000000000000602082015250565b60006155856037836149d5565b915061559082615529565b603782019050919050565b7f227d205d00000000000000000000000000000000000000000000000000000000600082015250565b60006155d16004836149d5565b91506155dc8261559b565b600482019050919050565b60006155f282615092565b91506155fe828f614a2c565b915061560982615104565b9150615615828e614a2c565b915061562082615176565b915061562c828d614a2c565b9150615637826151e8565b9150615643828c614a2c565b915061564e8261525a565b915061565a828b614a2c565b9150615665826152cc565b9150615671828a614a2c565b915061567c8261533e565b91506156888289614a2c565b9150615693826153b0565b915061569f8288614a2c565b91506156aa82615422565b91506156b68287614a2c565b91506156c182615494565b91506156cd8286614a2c565b91506156d882615506565b91506156e48285614a2c565b91506156ef82615578565b91506156fb8284614a2c565b9150615706826155c4565b91508190509d9c50505050505050505050505050565b60006040820190506157316000830185613667565b61573e6020830184613ac9565b9392505050565b60008082015250565b600061575b6001836149d5565b915061576682615745565b600182019050919050565b600061577c8261574e565b91506157888284614ecb565b915081905092915050565b7f600b5981380380925939f3000000000000000000000000000000000000000000600082015250565b60006157c9600b836149d5565b91506157d482615793565b600b82019050919050565b60006157ea826157bc565b91506157f68284614ecb565b915081905092915050565b7f4445504c4f594d454e545f4641494c4544000000000000000000000000000000600082015250565b600061583760118361355d565b915061584282615801565b602082019050919050565b600060208201905081810360008301526158668161582a565b9050919050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323060008201527f30302f73766722207072657365727665417370656374526174696f3d22784d6960208201527f64594d6964206d656574222076696577426f783d220000000000000000000000604082015250565b60006158ef6055836149d5565b91506158fa8261586d565b605582019050919050565b7f22207374796c653d226261636b67726f756e642d636f6c6f723a000000000000600082015250565b600061593b601a836149d5565b915061594682615905565b601a82019050919050565b7f223e000000000000000000000000000000000000000000000000000000000000600082015250565b60006159876002836149d5565b915061599282615951565b600282019050919050565b60006159a8826158e2565b91506159b48285614a2c565b91506159bf8261592e565b91506159cb8284614a2c565b91506159d68261597a565b91508190509392505050565b7f3c7374796c653e00000000000000000000000000000000000000000000000000600082015250565b6000615a186007836149d5565b9150615a23826159e2565b600782019050919050565b7f406b65796672616d657320676c6f77207b3025207b66696c7465723a2064726f60008201527f702d736861646f77283136707820313670782032307078200000000000000000602082015250565b6000615a8a6038836149d5565b9150615a9582615a2e565b603882019050919050565b7f29206272696768746e6573732800000000000000000000000000000000000000600082015250565b6000615ad6600d836149d5565b9150615ae182615aa0565b600d82019050919050565b7f25293b7d746f207b66696c7465723a2064726f702d736861646f77283136707860008201527f2031367078203230707820000000000000000000000000000000000000000000602082015250565b6000615b48602b836149d5565b9150615b5382615aec565b602b82019050919050565b7f25293b7d7d70617468207b66696c6c3a20000000000000000000000000000000600082015250565b6000615b946011836149d5565b9150615b9f82615b5e565b601182019050919050565b7f3b616e696d6174696f6e3a20676c6f7720000000000000000000000000000000600082015250565b6000615be06011836149d5565b9150615beb82615baa565b601182019050919050565b7f7320656173652d696e2d6f757420696e66696e69746520616c7465726e61746560008201527f3b7d2e79616b207b66696c6c3a20000000000000000000000000000000000000602082015250565b6000615c52602e836149d5565b9150615c5d82615bf6565b602e82019050919050565b7f3b7d2e79616b3a686f766572207b66696c6c3a20000000000000000000000000600082015250565b6000615c9e6014836149d5565b9150615ca982615c68565b601482019050919050565b7f3b7d2e69636f6e207b66696c6c3a200000000000000000000000000000000000600082015250565b6000615cea600f836149d5565b9150615cf582615cb4565b600f82019050919050565b7f3b7d3c2f7374796c653e00000000000000000000000000000000000000000000600082015250565b6000615d36600a836149d5565b9150615d4182615d00565b600a82019050919050565b6000615d5782615a0b565b9150615d6282615a7d565b9150615d6e828c614a2c565b9150615d7982615ac9565b9150615d85828b614a2c565b9150615d9082615b3b565b9150615d9c828a614a2c565b9150615da782615ac9565b9150615db38289614a2c565b9150615dbe82615b87565b9150615dca8288614a2c565b9150615dd582615bd3565b9150615de18287614a2c565b9150615dec82615c45565b9150615df88286614a2c565b9150615e0382615c91565b9150615e0f8285614a2c565b9150615e1a82615cdd565b9150615e268284614a2c565b9150615e3182615d29565b91508190509a9950505050505050505050565b7f3c73766720000000000000000000000000000000000000000000000000000000600082015250565b6000615e7a6005836149d5565b9150615e8582615e44565b600582019050919050565b7f3e20000000000000000000000000000000000000000000000000000000000000600082015250565b6000615ec66002836149d5565b9150615ed182615e90565b600282019050919050565b6000615ee782615e6d565b9150615ef38286614a2c565b9150615eff8285614a2c565b9150615f0a82615eb9565b9150615f168284614a2c565b9150615f2182614fd7565b915081905094935050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220cf42a4257216fe1e7138d6bf64f60b7b53428b0b904e3574c22dada2253a66b764736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000017a166d08ee8b2a7b3bd056d22eb5300b3652f49
-----Decoded View---------------
Arg [0] : zlib_ (address): 0x17A166d08Ee8b2A7b3Bd056D22EB5300b3652F49
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000017a166d08ee8b2a7b3bd056d22eb5300b3652f49
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.