ArtToken1155: Token
Source Code
Token Contract
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 53 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Set Approval For... | 23589120 | 128 days ago | IN | 0 ETH | 0.00000647 | ||||
| Safe Transfer Fr... | 23589116 | 129 days ago | IN | 0 ETH | 0.00009559 | ||||
| Set Approval For... | 22993452 | 212 days ago | IN | 0 ETH | 0.00001254 | ||||
| Safe Transfer Fr... | 22993401 | 212 days ago | IN | 0 ETH | 0.0001361 | ||||
| Mint | 21080607 | 479 days ago | IN | 0 ETH | 0.00039765 | ||||
| Mint | 21080601 | 479 days ago | IN | 0 ETH | 0.00055778 | ||||
| Mint | 21080595 | 479 days ago | IN | 0 ETH | 0.00036295 | ||||
| Mint | 21080050 | 479 days ago | IN | 0 ETH | 0.00063923 | ||||
| Mint | 21079805 | 479 days ago | IN | 0 ETH | 0.00089745 | ||||
| Mint | 21079803 | 479 days ago | IN | 0 ETH | 0.00115791 | ||||
| Safe Transfer Fr... | 20865945 | 509 days ago | IN | 0 ETH | 0.00056514 | ||||
| Mint | 19971497 | 634 days ago | IN | 0 ETH | 0.00053366 | ||||
| Mint | 19971497 | 634 days ago | IN | 0 ETH | 0.00053342 | ||||
| Mint | 19971496 | 634 days ago | IN | 0 ETH | 0.00056228 | ||||
| Mint | 19971495 | 634 days ago | IN | 0 ETH | 0.00052324 | ||||
| Set Approval For... | 18743921 | 806 days ago | IN | 0 ETH | 0.00202997 | ||||
| Set Approval For... | 18743889 | 806 days ago | IN | 0 ETH | 0.00189284 | ||||
| Set Approval For... | 18236410 | 877 days ago | IN | 0 ETH | 0.00078675 | ||||
| Set Approval For... | 18230104 | 878 days ago | IN | 0 ETH | 0.00038907 | ||||
| Safe Transfer Fr... | 18230084 | 878 days ago | IN | 0 ETH | 0.00031054 | ||||
| Set Approval For... | 18188709 | 884 days ago | IN | 0 ETH | 0.00063664 | ||||
| Set Approval For... | 18183259 | 884 days ago | IN | 0 ETH | 0.00052126 | ||||
| Set Approval For... | 17944028 | 918 days ago | IN | 0 ETH | 0.0011955 | ||||
| Set Approval For... | 17944028 | 918 days ago | IN | 0 ETH | 0.00119397 | ||||
| Safe Transfer Fr... | 17695136 | 953 days ago | IN | 0 ETH | 0.0008551 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ArtToken1155
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
import { ERC1155 } from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
/**
* @notice ERC1155 token with on-chain generative art.
* @author Ryan Ghods (ralxz.eth)
*/
contract ArtToken1155 is ERC1155, Ownable {
/**
* @notice Store the int representation of this address as a
* seed for its tokens' randomized output.
*/
uint160 private immutable thisUintAddress = uint160(address(this));
/**
* @notice Deploy the token contract with its name and symbol.
*/
constructor() ERC1155('') {
for (uint i = 0; i < 25; i++) {
_mint(msg.sender, i, 25, '');
_mint(0x1108f964b384f1dCDa03658B24310ccBc48E226F, i, 25, '');
}
}
function contractURI() public pure returns (string memory) {
string memory json = '{"name": "ArtToken- 1155","description":"A test token"}';
return string.concat("data:application/json;utf8,", json);
}
function mint(address to, uint256 id, uint256 amount, bytes memory data) external virtual onlyOwner {
_mint(to, id, amount, data);
}
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external virtual onlyOwner {
_mintBatch(to, ids, amounts, data);
}
/**
* @notice Returns the token URI for the token id.
*/
function uri(uint256 tokenId)
public
view
virtual
override returns (string memory) {
return _tokenJson(tokenId);
}
/**
* @notice Returns the json for the token id.
*/
function _tokenJson(uint256 tokenId) internal view returns (string memory) {
string memory svg;
string memory rect = _randomRect(tokenId);
string memory poly = _randomPolygon(tokenId);
string memory circle = _randomCircle(tokenId);
svg = string.concat(
svg,
"<svg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='xMinYMin meet' viewBox='0 0 350 350'>"
"<rect width='100%' height='100%' style='fill:",
_randomColor(tokenId, true),
"' /><text x='50%' y='50%' dominant-baseline='middle' text-anchor='middle' style='fill:",
_randomColor(tokenId + 1, false),
";font-family:",
_font(tokenId),
";font-size:",
_fontSize(tokenId),
"px;",
_randomStyle(tokenId, 1),
"'>",
Strings.toString(tokenId),
"</text>",
rect,
poly,
circle,
"</svg>"
);
string memory json = '{"name": "#';
json = string.concat(json, Strings.toString(tokenId),
'", "description": "This is an example test token, for trying out cool things related to NFTs :)'
' Please note that this token has no value or warranty of any kind.\\n\\n\\"The future'
' belongs to those who believe in the beauty of their dreams.\\"\\n-Eleanor Roosevelt", "image_data": "',
svg,
'", "attributes": [ {"trait_type": "Token ID", "value": "',
Strings.toString(tokenId),
'"}, {"trait_type": "Font", "value": "',
_font(tokenId),
'"}, {"trait_type": "Font size", "value": "',
_fontSize(tokenId),
'"}, {"trait_type": "Rectangle", "value": "',
_returnYesOrNo(rect),
'"}, {"trait_type": "Triangle", "value": "',
_returnYesOrNo(poly),
'"}, {"trait_type": "Circle", "value": "',
_returnYesOrNo(circle),
'"}, {"trait_type": "Chain ID", "value": "',
Strings.toString(block.chainid),
'"}]}');
return string.concat("data:application/json;utf8,", json);
}
/**
* @notice Returns "No" if the input string is empty, otherwise "Yes",
* for formatting metadata traits.
*/
function _returnYesOrNo(string memory input)
internal
pure
returns (string memory)
{
return bytes(input).length == 0 ? "No" : "Yes";
}
/**
* @notice Returns a random web safe font based on the token id.
*/
function _font(uint256 tokenId) internal view returns (string memory) {
uint256 roll = (thisUintAddress / tokenId) >> 1;
if (roll % 13 == 0) {
return "Courier New";
} else if (roll % 9 == 0) {
return "Garamond";
} else if (roll % 8 == 0) {
return "Tahoma";
} else if (roll % 7 == 0) {
return "Trebuchet MS";
} else if (roll % 6 == 0) {
return "Times New Roman";
} else if (roll % 5 == 0) {
return "Georgia";
} else if (roll % 4 == 0) {
return "Helvetica";
} else {
return "Brush Script MT";
}
}
/**
* @notice Returns a random font size based on the token id.
*/
function _fontSize(uint256 tokenId) internal view returns (string memory) {
uint256 roll = (thisUintAddress / tokenId) >> 2;
return Strings.toString((roll % 180) + 12);
}
/**
* @notice Returns a random color based on the token id.
*/
function _randomColor(uint256 tokenId, bool onlyPastel)
internal
view
returns (string memory)
{
uint256 roll = (thisUintAddress / tokenId) >> 3;
string memory color = "rgb(";
uint256 pastelBase = onlyPastel == true ? 127 : 0;
uint256 r = ((roll >> 1) % (255 - pastelBase)) + pastelBase;
uint256 g = ((roll >> 2) % (255 - pastelBase)) + pastelBase;
uint256 b = ((roll >> 3) % (255 - pastelBase)) + pastelBase;
color = string.concat(color, Strings.toString(r),
", ",
Strings.toString(g),
", ",
Strings.toString(b),
")");
return color;
}
/**
* @notice Returns a random rectangle...sometimes.
*/
function _randomRect(uint256 tokenId)
internal
view
returns (string memory)
{
uint256 roll = (thisUintAddress / tokenId) >> 4;
if (roll % 3 != 0) return "";
string memory rect = "<rect x='";
uint256 x = (roll >> 1) % 301;
uint256 y = (roll >> 2) % 302;
uint256 width = (roll >> 3) % 303;
uint256 height = (roll >> 4) % 303;
rect = string.concat(rect, Strings.toString(x),
"' y='",
Strings.toString(y),
"' width='",
Strings.toString(width),
"' height='",
Strings.toString(height),
"' style='",
_randomStyle(tokenId, 3),
"' />");
return rect;
}
/**
* @notice Returns a random polygon...sometimes.
*/
function _randomPolygon(uint256 tokenId)
internal
view
returns (string memory)
{
uint256 roll = (thisUintAddress / tokenId) >> 5;
if (roll % 5 != 0) return "";
string memory poly = "<polygon points='";
uint256 x1 = (roll >> 1) % 301;
uint256 y1 = (roll >> 2) % 302;
uint256 x2 = (roll >> 3) % 303;
uint256 y2 = (roll >> 4) % 304;
uint256 x3 = (roll >> 5) % 305;
uint256 y3 = (roll >> 6) % 306;
poly = string.concat(poly, Strings.toString(x1), ",", Strings.toString(y1), " ", Strings.toString(x2), ",", Strings.toString(y2), " ", Strings.toString(x3), ",", Strings.toString(y3));
poly = string.concat("' style='", _randomStyle(tokenId, 5), "' />");
return poly;
}
/**
* @notice Returns a random circle...sometimes.
*/
function _randomCircle(uint256 tokenId)
internal
view
returns (string memory)
{
uint256 roll = (thisUintAddress / tokenId) >> 6;
if (roll % 7 != 0) return "";
string memory circle = "<circle cx='";
uint256 cx = (roll >> 1) % 300;
uint256 cy = (roll >> 2) % 300;
uint256 r = (roll >> 3) % 150;
circle = string.concat(circle, Strings.toString(cx), "' cy='", Strings.toString(cy), "' r='", Strings.toString(r), "' style='", _randomStyle(tokenId, 7), "' />");
return circle;
}
/**
* @notice Returns a random style of fill color, fill opacity,
* stroke width, stroke opacity, and dasharray.
*/
function _randomStyle(uint256 tokenId, uint256 seed)
internal
view
returns (string memory)
{
string memory style = "fill:";
style = string.concat(style, _randomColor(tokenId + seed + 1, true), ";fill-opacity:.", Strings.toString(_randomOpacity(tokenId + seed + 3)));
if (((tokenId + seed) * 3) % 4 == 0) {
style = string.concat(style, ";stroke:", _randomColor(tokenId + seed + 5, false), ";stroke-width:", Strings.toString(_randomStrokeWidth(tokenId + seed + 7)), ";stroke-opacity:.", Strings.toString(_randomOpacity(tokenId + seed + 9)));
if ((tokenId + seed) % 5 == 0) {
style = string.concat(style, ";stroke-dasharray:", Strings.toString(_randomStrokeWidth(tokenId + seed + 13)));
}
}
return style;
}
/**
* @notice Returns a random fill opacity from 1 to 9,
* to be prepended with a decimal in the css.
*/
function _randomOpacity(uint256 tokenId) internal view returns (uint256) {
uint256 roll = (thisUintAddress / tokenId) >> 3;
return (roll % 9) + 1;
}
/**
* @notice Returns a random stroke width from 0 to 9.
*/
function _randomStrokeWidth(uint256 tokenId)
internal
view
returns (uint256)
{
uint256 roll = (thisUintAddress / tokenId) >> 4;
return roll % 10;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol)
pragma solidity ^0.8.0;
import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of the basic standard multi-token.
* See https://eips.ethereum.org/EIPS/eip-1155
* Originally based on code by Enjin: https://github.com/enjin/erc-1155
*
* _Available since v3.1._
*/
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
using Address for address;
// Mapping from token ID to account balances
mapping(uint256 => mapping(address => uint256)) private _balances;
// Mapping from account to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
string private _uri;
/**
* @dev See {_setURI}.
*/
constructor(string memory uri_) {
_setURI(uri_);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC1155).interfaceId ||
interfaceId == type(IERC1155MetadataURI).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC1155MetadataURI-uri}.
*
* This implementation returns the same URI for *all* token types. It relies
* on the token type ID substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* Clients calling this function must replace the `\{id\}` substring with the
* actual token type ID.
*/
function uri(uint256) public view virtual override returns (string memory) {
return _uri;
}
/**
* @dev See {IERC1155-balanceOf}.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
require(account != address(0), "ERC1155: address zero is not a valid owner");
return _balances[id][account];
}
/**
* @dev See {IERC1155-balanceOfBatch}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
public
view
virtual
override
returns (uint256[] memory)
{
require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
uint256[] memory batchBalances = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) {
batchBalances[i] = balanceOf(accounts[i], ids[i]);
}
return batchBalances;
}
/**
* @dev See {IERC1155-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC1155-isApprovedForAll}.
*/
function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
return _operatorApprovals[account][operator];
}
/**
* @dev See {IERC1155-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner or approved"
);
_safeTransferFrom(from, to, id, amount, data);
}
/**
* @dev See {IERC1155-safeBatchTransferFrom}.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override {
require(
from == _msgSender() || isApprovedForAll(from, _msgSender()),
"ERC1155: caller is not token owner or approved"
);
_safeBatchTransferFrom(from, to, ids, amounts, data);
}
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
emit TransferSingle(operator, from, to, id, amount);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
require(to != address(0), "ERC1155: transfer to the zero address");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; ++i) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
unchecked {
_balances[id][from] = fromBalance - amount;
}
_balances[id][to] += amount;
}
emit TransferBatch(operator, from, to, ids, amounts);
_afterTokenTransfer(operator, from, to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
}
/**
* @dev Sets a new URI for all token types, by relying on the token type ID
* substitution mechanism
* https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
*
* By this mechanism, any occurrence of the `\{id\}` substring in either the
* URI or any of the amounts in the JSON file at said URI will be replaced by
* clients with the token type ID.
*
* For example, the `https://token-cdn-domain/\{id\}.json` URI would be
* interpreted by clients as
* `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
* for token type ID 0x4cce0.
*
* See {uri}.
*
* Because these URIs cannot be meaningfully represented by the {URI} event,
* this function emits no events.
*/
function _setURI(string memory newuri) internal virtual {
_uri = newuri;
}
/**
* @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function _mint(
address to,
uint256 id,
uint256 amount,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
_balances[id][to] += amount;
emit TransferSingle(operator, address(0), to, id, amount);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function _mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {
require(to != address(0), "ERC1155: mint to the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
for (uint256 i = 0; i < ids.length; i++) {
_balances[ids[i]][to] += amounts[i];
}
emit TransferBatch(operator, address(0), to, ids, amounts);
_afterTokenTransfer(operator, address(0), to, ids, amounts, data);
_doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
}
/**
* @dev Destroys `amount` tokens of token type `id` from `from`
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `from` must have at least `amount` tokens of token type `id`.
*/
function _burn(
address from,
uint256 id,
uint256 amount
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
address operator = _msgSender();
uint256[] memory ids = _asSingletonArray(id);
uint256[] memory amounts = _asSingletonArray(amount);
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
emit TransferSingle(operator, from, address(0), id, amount);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
*/
function _burnBatch(
address from,
uint256[] memory ids,
uint256[] memory amounts
) internal virtual {
require(from != address(0), "ERC1155: burn from the zero address");
require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
address operator = _msgSender();
_beforeTokenTransfer(operator, from, address(0), ids, amounts, "");
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
uint256 amount = amounts[i];
uint256 fromBalance = _balances[id][from];
require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
unchecked {
_balances[id][from] = fromBalance - amount;
}
}
emit TransferBatch(operator, from, address(0), ids, amounts);
_afterTokenTransfer(operator, from, address(0), ids, amounts, "");
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits an {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC1155: setting approval status for self");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `ids` and `amounts` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
/**
* @dev Hook that is called after any token transfer. This includes minting
* and burning, as well as batched variants.
*
* The same hook is called on both single and batched variants. For single
* transfers, the length of the `id` and `amount` arrays will be 1.
*
* Calling conditions (for each `id` and `amount` pair):
*
* - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* of token type `id` will be transferred to `to`.
* - When `from` is zero, `amount` tokens of token type `id` will be minted
* for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
* will be burned.
* - `from` and `to` are never both zero.
* - `ids` and `amounts` have the same, non-zero length.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) internal virtual {}
function _doSafeTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
if (response != IERC1155Receiver.onERC1155Received.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non-ERC1155Receiver implementer");
}
}
}
function _doSafeBatchTransferAcceptanceCheck(
address operator,
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) private {
if (to.isContract()) {
try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
bytes4 response
) {
if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
revert("ERC1155: ERC1155Receiver rejected tokens");
}
} catch Error(string memory reason) {
revert(reason);
} catch {
revert("ERC1155: transfer to non-ERC1155Receiver implementer");
}
}
}
function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](1);
array[0] = element;
return array;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./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);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)
pragma solidity ^0.8.0;
import "../IERC1155.sol";
/**
* @dev Interface of the optional ERC1155MetadataExtension interface, as defined
* in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
*
* _Available since v3.1._
*/
interface IERC1155MetadataURI is IERC1155 {
/**
* @dev Returns the URI for token type `id`.
*
* If the `\{id\}` substring is present in the URI, it must be replaced by
* clients with the actual token type ID.
*/
function uri(uint256 id) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155Receiver is IERC165 {
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a06040523073ffffffffffffffffffffffffffffffffffffffff1660809073ffffffffffffffffffffffffffffffffffffffff168152503480156200004457600080fd5b506040518060200160405280600081525062000066816200010d60201b60201c565b50620000876200007b6200012260201b60201c565b6200012a60201b60201c565b60005b60198110156200010657620000b83382601960405180602001604052806000815250620001f060201b60201c565b620000f0731108f964b384f1dcda03658b24310ccbc48e226f82601960405180602001604052806000815250620001f060201b60201c565b8080620000fd90620006bd565b9150506200008a565b506200102b565b80600290816200011e91906200097a565b5050565b600033905090565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160362000262576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002599062000ae8565b60405180910390fd5b6000620002746200012260201b60201c565b905060006200028985620003d760201b60201c565b905060006200029e85620003d760201b60201c565b9050620002b7836000898585896200045860201b60201c565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825462000318919062000b0a565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516200039892919062000b56565b60405180910390a4620003b7836000898585896200046060201b60201c565b620003ce836000898989896200046860201b60201c565b50505050505050565b60606000600167ffffffffffffffff811115620003f957620003f862000715565b5b604051908082528060200260200182016040528015620004285781602001602082028036833780820191505090505b509050828160008151811062000443576200044262000b83565b5b60200260200101818152505080915050919050565b505050505050565b505050505050565b620004948473ffffffffffffffffffffffffffffffffffffffff166200066160201b620008c71760201c565b1562000659578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401620004dd95949392919062000c91565b6020604051808303816000875af19250505080156200051c57506040513d601f19601f8201168201806040525081019062000519919062000d61565b60015b620005cd576200052b62000da0565b806308c379a0036200058e57506200054262000dfb565b806200054f575062000590565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000585919062000ed7565b60405180910390fd5b505b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005c49062000f71565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161462000657576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200064e9062001009565b60405180910390fd5b505b505050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000620006ca82620006b3565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620006ff57620006fe62000684565b5b600182019050919050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200078c57607f821691505b602082108103620007a257620007a162000744565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200080c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620007cd565b620008188683620007cd565b95508019841693508086168417925050509392505050565b6000819050919050565b60006200085b620008556200084f84620006b3565b62000830565b620006b3565b9050919050565b6000819050919050565b62000877836200083a565b6200088f620008868262000862565b848454620007da565b825550505050565b600090565b620008a662000897565b620008b38184846200086c565b505050565b5b81811015620008db57620008cf6000826200089c565b600181019050620008b9565b5050565b601f8211156200092a57620008f481620007a8565b620008ff84620007bd565b810160208510156200090f578190505b620009276200091e85620007bd565b830182620008b8565b50505b505050565b600082821c905092915050565b60006200094f600019846008026200092f565b1980831691505092915050565b60006200096a83836200093c565b9150826002028217905092915050565b62000985826200070a565b67ffffffffffffffff811115620009a157620009a062000715565b5b620009ad825462000773565b620009ba828285620008df565b600060209050601f831160018114620009f25760008415620009dd578287015190505b620009e985826200095c565b86555062000a59565b601f19841662000a0286620007a8565b60005b8281101562000a2c5784890151825560018201915060208501945060208101905062000a05565b8683101562000a4c578489015162000a48601f8916826200093c565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600062000ad060218362000a61565b915062000add8262000a72565b604082019050919050565b6000602082019050818103600083015262000b038162000ac1565b9050919050565b600062000b1782620006b3565b915062000b2483620006b3565b925082820190508082111562000b3f5762000b3e62000684565b5b92915050565b62000b5081620006b3565b82525050565b600060408201905062000b6d600083018562000b45565b62000b7c602083018462000b45565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000bdf8262000bb2565b9050919050565b62000bf18162000bd2565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101562000c3357808201518184015260208101905062000c16565b60008484015250505050565b6000601f19601f8301169050919050565b600062000c5d8262000bf7565b62000c69818562000c02565b935062000c7b81856020860162000c13565b62000c868162000c3f565b840191505092915050565b600060a08201905062000ca8600083018862000be6565b62000cb7602083018762000be6565b62000cc6604083018662000b45565b62000cd5606083018562000b45565b818103608083015262000ce9818462000c50565b90509695505050505050565b6000604051905090565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62000d3b8162000d04565b811462000d4757600080fd5b50565b60008151905062000d5b8162000d30565b92915050565b60006020828403121562000d7a5762000d7962000cff565b5b600062000d8a8482850162000d4a565b91505092915050565b60008160e01c9050919050565b600060033d111562000dc25760046000803e62000dbf60005162000d93565b90505b90565b62000dd08262000c3f565b810181811067ffffffffffffffff8211171562000df25762000df162000715565b5b80604052505050565b600060443d1062000e935762000e1062000cf5565b60043d036004823e80513d602482011167ffffffffffffffff8211171562000e3a57505062000e93565b808201805167ffffffffffffffff81111562000e5a575050505062000e93565b80602083010160043d03850181111562000e7957505050505062000e93565b62000e8a8260200185018662000dc5565b82955050505050505b90565b600062000ea3826200070a565b62000eaf818562000a61565b935062000ec181856020860162000c13565b62000ecc8162000c3f565b840191505092915050565b6000602082019050818103600083015262000ef3818462000e96565b905092915050565b7f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b600062000f5960348362000a61565b915062000f668262000efb565b604082019050919050565b6000602082019050818103600083015262000f8c8162000f4a565b9050919050565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b600062000ff160288362000a61565b915062000ffe8262000f93565b604082019050919050565b60006020820190508181036000830152620010248162000fe2565b9050919050565b608051614f1c62001078600039600081816117270152818161189601528181611a6701528181611bb401528181611d2701528181611ff0015281816127d0015261283c0152614f1c6000f3fe608060405234801561001057600080fd5b50600436106100e95760003560e01c8063731133e91161008c578063e8a3d48511610066578063e8a3d48514610246578063e985e9c514610264578063f242432a14610294578063f2fde38b146102b0576100e9565b8063731133e9146101f05780638da5cb5b1461020c578063a22cb4651461022a576100e9565b80631f7fdffa116100c85780631f7fdffa1461017e5780632eb2c2d61461019a5780634e1273f4146101b6578063715018a6146101e6576100e9565b8062fdd58e146100ee57806301ffc9a71461011e5780630e89341c1461014e575b600080fd5b61010860048036038101906101039190612a8f565b6102cc565b6040516101159190612ade565b60405180910390f35b61013860048036038101906101339190612b51565b610394565b6040516101459190612b99565b60405180910390f35b61016860048036038101906101639190612bb4565b610476565b6040516101759190612c71565b60405180910390f35b61019860048036038101906101939190612e90565b610488565b005b6101b460048036038101906101af9190612f4b565b6104a2565b005b6101d060048036038101906101cb91906130dd565b610543565b6040516101dd9190613213565b60405180910390f35b6101ee61065c565b005b61020a60048036038101906102059190613235565b610670565b005b61021461068a565b60405161022191906132c7565b60405180910390f35b610244600480360381019061023f919061330e565b6106b4565b005b61024e6106ca565b60405161025b9190612c71565b60405180910390f35b61027e6004803603810190610279919061334e565b61070f565b60405161028b9190612b99565b60405180910390f35b6102ae60048036038101906102a9919061338e565b6107a3565b005b6102ca60048036038101906102c59190613425565b610844565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361033c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610333906134c4565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061045f57507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061046f575061046e826108ea565b5b9050919050565b606061048182610954565b9050919050565b610490610ace565b61049c84848484610b4c565b50505050565b6104aa610d78565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806104f057506104ef856104ea610d78565b61070f565b5b61052f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052690613556565b60405180910390fd5b61053c8585858585610d80565b5050505050565b60608151835114610589576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906135e8565b60405180910390fd5b6000835167ffffffffffffffff8111156105a6576105a5612c98565b5b6040519080825280602002602001820160405280156105d45781602001602082028036833780820191505090505b50905060005b8451811015610651576106218582815181106105f9576105f8613608565b5b602002602001015185838151811061061457610613613608565b5b60200260200101516102cc565b82828151811061063457610633613608565b5b6020026020010181815250508061064a90613666565b90506105da565b508091505092915050565b610664610ace565b61066e60006110a1565b565b610678610ace565b61068484848484611167565b50505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6106c66106bf610d78565b8383611317565b5050565b60606000604051806060016040528060378152602001614eb0603791399050806040516020016106fa9190613710565b60405160208183030381529060405291505090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6107ab610d78565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806107f157506107f0856107eb610d78565b61070f565b5b610830576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082790613556565b60405180910390fd5b61083d8585858585611483565b5050505050565b61084c610ace565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b2906137a8565b60405180910390fd5b6108c4816110a1565b50565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60608060006109628461171e565b9050600061096f8561188d565b9050600061097c86611a5e565b90508361098a876001611bab565b6109a160018961099a91906137c8565b6000611bab565b6109aa89611d1e565b6109b38a611fe7565b6109be8b600161205c565b6109c78c61223e565b8989896040516020016109e39a99989796959493929190613a5c565b604051602081830303815290604052935060006040518060400160405280600b81526020017f7b226e616d65223a202223000000000000000000000000000000000000000000815250905080610a388861223e565b86610a428a61223e565b610a4b8b611d1e565b610a548c611fe7565b610a5d8a61230c565b610a668a61230c565b610a6f8a61230c565b610a784661223e565b604051602001610a919a9998979695949392919061401b565b604051602081830303815290604052905080604051602001610ab39190613710565b60405160208183030381529060405295505050505050919050565b610ad6610d78565b73ffffffffffffffffffffffffffffffffffffffff16610af461068a565b73ffffffffffffffffffffffffffffffffffffffff1614610b4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b419061415a565b60405180910390fd5b565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610bbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb2906141ec565b60405180910390fd5b8151835114610bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf69061427e565b60405180910390fd5b6000610c09610d78565b9050610c1a81600087878787612390565b60005b8451811015610cd357838181518110610c3957610c38613608565b5b6020026020010151600080878481518110610c5757610c56613608565b5b6020026020010151815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610cb991906137c8565b925050819055508080610ccb90613666565b915050610c1d565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610d4b92919061429e565b60405180910390a4610d6281600087878787612398565b610d71816000878787876123a0565b5050505050565b600033905090565b8151835114610dc4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbb9061427e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2a90614347565b60405180910390fd5b6000610e3d610d78565b9050610e4d818787878787612390565b60005b8451811015610ffe576000858281518110610e6e57610e6d613608565b5b602002602001015190506000858381518110610e8d57610e8c613608565b5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610f2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f25906143d9565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610fe391906137c8565b9250508190555050505080610ff790613666565b9050610e50565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161107592919061429e565b60405180910390a461108b818787878787612398565b6110998187878787876123a0565b505050505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036111d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111cd906141ec565b60405180910390fd5b60006111e0610d78565b905060006111ed85612577565b905060006111fa85612577565b905061120b83600089858589612390565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461126a91906137c8565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516112e89291906143f9565b60405180910390a46112ff83600089858589612398565b61130e836000898989896125f1565b50505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611385576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137c90614494565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516114769190612b99565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036114f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e990614347565b60405180910390fd5b60006114fc610d78565b9050600061150985612577565b9050600061151685612577565b9050611526838989858589612390565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050858110156115bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b4906143d9565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461167291906137c8565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a6040516116ef9291906143f9565b60405180910390a4611705848a8a86868a612398565b611713848a8a8a8a8a6125f1565b505050505050505050565b606060006004837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661176691906144e3565b901c905060006003826117799190614514565b146117965760405180602001604052806000815250915050611888565b60006040518060400160405280600981526020017f3c7265637420783d2700000000000000000000000000000000000000000000008152509050600061012d600184901c6117e49190614514565b9050600061012e600285901c6117fa9190614514565b9050600061012f600386901c6118109190614514565b9050600061012f600487901c6118269190614514565b9050846118328561223e565b61183b8561223e565b6118448561223e565b61184d8561223e565b6118588d600361205c565b60405160200161186d96959493929190614603565b60405160208183030381529060405294508496505050505050505b919050565b606060006005837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166118d591906144e3565b901c905060006005826118e89190614514565b146119055760405180602001604052806000815250915050611a59565b60006040518060400160405280601181526020017f3c706f6c79676f6e20706f696e74733d270000000000000000000000000000008152509050600061012d600184901c6119539190614514565b9050600061012e600285901c6119699190614514565b9050600061012f600386901c61197f9190614514565b90506000610130600487901c6119959190614514565b90506000610131600588901c6119ab9190614514565b90506000610132600689901c6119c19190614514565b9050866119cd8761223e565b6119d68761223e565b6119df8761223e565b6119e88761223e565b6119f18761223e565b6119fa8761223e565b604051602001611a1097969594939291906146f2565b6040516020818303038152906040529650611a2c8a600561205c565b604051602001611a3c91906147a2565b604051602081830303815290604052965086985050505050505050505b919050565b606060006006837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611aa691906144e3565b901c90506000600782611ab99190614514565b14611ad65760405180602001604052806000815250915050611ba6565b60006040518060400160405280600c81526020017f3c636972636c652063783d2700000000000000000000000000000000000000008152509050600061012c600184901c611b249190614514565b9050600061012c600285901c611b3a9190614514565b905060006096600386901c611b4f9190614514565b905083611b5b8461223e565b611b648461223e565b611b6d8461223e565b611b788b600761205c565b604051602001611b8c959493929190614823565b604051602081830303815290604052935083955050505050505b919050565b606060006003847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611bf391906144e3565b901c905060006040518060400160405280600481526020017f7267622800000000000000000000000000000000000000000000000000000000815250905060006001151585151514611c46576000611c49565b607f5b60ff1690506000818260ff611c5e91906148aa565b600186901c611c6d9190614514565b611c7791906137c8565b90506000828360ff611c8991906148aa565b600287901c611c989190614514565b611ca291906137c8565b90506000838460ff611cb491906148aa565b600388901c611cc39190614514565b611ccd91906137c8565b905084611cd98461223e565b611ce28461223e565b611ceb8461223e565b604051602001611cfe949392919061492a565b604051602081830303815290604052945084965050505050505092915050565b606060006001837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611d6691906144e3565b901c90506000600d82611d799190614514565b03611dbc576040518060400160405280600b81526020017f436f7572696572204e6577000000000000000000000000000000000000000000815250915050611fe2565b6000600982611dcb9190614514565b03611e0e576040518060400160405280600881526020017f476172616d6f6e64000000000000000000000000000000000000000000000000815250915050611fe2565b6000600882611e1d9190614514565b03611e60576040518060400160405280600681526020017f5461686f6d610000000000000000000000000000000000000000000000000000815250915050611fe2565b6000600782611e6f9190614514565b03611eb2576040518060400160405280600c81526020017f547265627563686574204d530000000000000000000000000000000000000000815250915050611fe2565b6000600682611ec19190614514565b03611f04576040518060400160405280600f81526020017f54696d6573204e657720526f6d616e0000000000000000000000000000000000815250915050611fe2565b6000600582611f139190614514565b03611f56576040518060400160405280600781526020017f47656f7267696100000000000000000000000000000000000000000000000000815250915050611fe2565b6000600482611f659190614514565b03611fa8576040518060400160405280600981526020017f48656c7665746963610000000000000000000000000000000000000000000000815250915050611fe2565b6040518060400160405280600f81526020017f427275736820536372697074204d5400000000000000000000000000000000008152509150505b919050565b606060006002837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661202f91906144e3565b901c9050612054600c60b4836120459190614514565b61204f91906137c8565b61223e565b915050919050565b606060006040518060400160405280600581526020017f66696c6c3a0000000000000000000000000000000000000000000000000000008152509050806120bb600185876120aa91906137c8565b6120b491906137c8565b6001611bab565b6120e36120de600387896120cf91906137c8565b6120d991906137c8565b6127c8565b61223e565b6040516020016120f5939291906149bb565b6040516020818303038152906040529050600060046003858761211891906137c8565b61212291906149fb565b61212c9190614514565b0361223457806121546005858761214391906137c8565b61214d91906137c8565b6000611bab565b61217c6121776007878961216891906137c8565b61217291906137c8565b612834565b61223e565b6121a461219f6009888a61219091906137c8565b61219a91906137c8565b6127c8565b61223e565b6040516020016121b79493929190614aaf565b60405160208183030381529060405290506000600584866121d891906137c8565b6121e29190614514565b03612233578061221061220b600d86886121fc91906137c8565b61220691906137c8565b612834565b61223e565b604051602001612221929190614b40565b60405160208183030381529060405290505b5b8091505092915050565b60606000600161224d84612894565b01905060008167ffffffffffffffff81111561226c5761226b612c98565b5b6040519080825280601f01601f19166020018201604052801561229e5781602001600182028036833780820191505090505b509050600082602001820190505b600115612301578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816122f5576122f46144b4565b5b049450600085036122ac575b819350505050919050565b60606000825114612352576040518060400160405280600381526020017f5965730000000000000000000000000000000000000000000000000000000000815250612389565b6040518060400160405280600281526020017f4e6f0000000000000000000000000000000000000000000000000000000000008152505b9050919050565b505050505050565b505050505050565b6123bf8473ffffffffffffffffffffffffffffffffffffffff166108c7565b1561256f578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b8152600401612405959493929190614bc8565b6020604051808303816000875af192505050801561244157506040513d601f19601f8201168201806040525081019061243e9190614c45565b60015b6124e65761244d614c7f565b806308c379a0036124a95750612461614ca1565b8061246c57506124ab565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124a09190612c71565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124dd90614da3565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461256d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256490614e35565b60405180910390fd5b505b505050505050565b60606000600167ffffffffffffffff81111561259657612595612c98565b5b6040519080825280602002602001820160405280156125c45781602001602082028036833780820191505090505b50905082816000815181106125dc576125db613608565b5b60200260200101818152505080915050919050565b6126108473ffffffffffffffffffffffffffffffffffffffff166108c7565b156127c0578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401612656959493929190614e55565b6020604051808303816000875af192505050801561269257506040513d601f19601f8201168201806040525081019061268f9190614c45565b60015b6127375761269e614c7f565b806308c379a0036126fa57506126b2614ca1565b806126bd57506126fc565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f19190612c71565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272e90614da3565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146127be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127b590614e35565b60405180910390fd5b505b505050505050565b6000806003837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661280f91906144e3565b901c905060016009826128229190614514565b61282c91906137c8565b915050919050565b6000806004837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661287b91906144e3565b901c9050600a8161288c9190614514565b915050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106128f2577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816128e8576128e76144b4565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061292f576d04ee2d6d415b85acef81000000008381612925576129246144b4565b5b0492506020810190505b662386f26fc10000831061295e57662386f26fc100008381612954576129536144b4565b5b0492506010810190505b6305f5e1008310612987576305f5e100838161297d5761297c6144b4565b5b0492506008810190505b61271083106129ac5761271083816129a2576129a16144b4565b5b0492506004810190505b606483106129cf57606483816129c5576129c46144b4565b5b0492506002810190505b600a83106129de576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612a26826129fb565b9050919050565b612a3681612a1b565b8114612a4157600080fd5b50565b600081359050612a5381612a2d565b92915050565b6000819050919050565b612a6c81612a59565b8114612a7757600080fd5b50565b600081359050612a8981612a63565b92915050565b60008060408385031215612aa657612aa56129f1565b5b6000612ab485828601612a44565b9250506020612ac585828601612a7a565b9150509250929050565b612ad881612a59565b82525050565b6000602082019050612af36000830184612acf565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b2e81612af9565b8114612b3957600080fd5b50565b600081359050612b4b81612b25565b92915050565b600060208284031215612b6757612b666129f1565b5b6000612b7584828501612b3c565b91505092915050565b60008115159050919050565b612b9381612b7e565b82525050565b6000602082019050612bae6000830184612b8a565b92915050565b600060208284031215612bca57612bc96129f1565b5b6000612bd884828501612a7a565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612c1b578082015181840152602081019050612c00565b60008484015250505050565b6000601f19601f8301169050919050565b6000612c4382612be1565b612c4d8185612bec565b9350612c5d818560208601612bfd565b612c6681612c27565b840191505092915050565b60006020820190508181036000830152612c8b8184612c38565b905092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cd082612c27565b810181811067ffffffffffffffff82111715612cef57612cee612c98565b5b80604052505050565b6000612d026129e7565b9050612d0e8282612cc7565b919050565b600067ffffffffffffffff821115612d2e57612d2d612c98565b5b602082029050602081019050919050565b600080fd5b6000612d57612d5284612d13565b612cf8565b90508083825260208201905060208402830185811115612d7a57612d79612d3f565b5b835b81811015612da35780612d8f8882612a7a565b845260208401935050602081019050612d7c565b5050509392505050565b600082601f830112612dc257612dc1612c93565b5b8135612dd2848260208601612d44565b91505092915050565b600080fd5b600067ffffffffffffffff821115612dfb57612dfa612c98565b5b612e0482612c27565b9050602081019050919050565b82818337600083830152505050565b6000612e33612e2e84612de0565b612cf8565b905082815260208101848484011115612e4f57612e4e612ddb565b5b612e5a848285612e11565b509392505050565b600082601f830112612e7757612e76612c93565b5b8135612e87848260208601612e20565b91505092915050565b60008060008060808587031215612eaa57612ea96129f1565b5b6000612eb887828801612a44565b945050602085013567ffffffffffffffff811115612ed957612ed86129f6565b5b612ee587828801612dad565b935050604085013567ffffffffffffffff811115612f0657612f056129f6565b5b612f1287828801612dad565b925050606085013567ffffffffffffffff811115612f3357612f326129f6565b5b612f3f87828801612e62565b91505092959194509250565b600080600080600060a08688031215612f6757612f666129f1565b5b6000612f7588828901612a44565b9550506020612f8688828901612a44565b945050604086013567ffffffffffffffff811115612fa757612fa66129f6565b5b612fb388828901612dad565b935050606086013567ffffffffffffffff811115612fd457612fd36129f6565b5b612fe088828901612dad565b925050608086013567ffffffffffffffff811115613001576130006129f6565b5b61300d88828901612e62565b9150509295509295909350565b600067ffffffffffffffff82111561303557613034612c98565b5b602082029050602081019050919050565b60006130596130548461301a565b612cf8565b9050808382526020820190506020840283018581111561307c5761307b612d3f565b5b835b818110156130a557806130918882612a44565b84526020840193505060208101905061307e565b5050509392505050565b600082601f8301126130c4576130c3612c93565b5b81356130d4848260208601613046565b91505092915050565b600080604083850312156130f4576130f36129f1565b5b600083013567ffffffffffffffff811115613112576131116129f6565b5b61311e858286016130af565b925050602083013567ffffffffffffffff81111561313f5761313e6129f6565b5b61314b85828601612dad565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61318a81612a59565b82525050565b600061319c8383613181565b60208301905092915050565b6000602082019050919050565b60006131c082613155565b6131ca8185613160565b93506131d583613171565b8060005b838110156132065781516131ed8882613190565b97506131f8836131a8565b9250506001810190506131d9565b5085935050505092915050565b6000602082019050818103600083015261322d81846131b5565b905092915050565b6000806000806080858703121561324f5761324e6129f1565b5b600061325d87828801612a44565b945050602061326e87828801612a7a565b935050604061327f87828801612a7a565b925050606085013567ffffffffffffffff8111156132a05761329f6129f6565b5b6132ac87828801612e62565b91505092959194509250565b6132c181612a1b565b82525050565b60006020820190506132dc60008301846132b8565b92915050565b6132eb81612b7e565b81146132f657600080fd5b50565b600081359050613308816132e2565b92915050565b60008060408385031215613325576133246129f1565b5b600061333385828601612a44565b9250506020613344858286016132f9565b9150509250929050565b60008060408385031215613365576133646129f1565b5b600061337385828601612a44565b925050602061338485828601612a44565b9150509250929050565b600080600080600060a086880312156133aa576133a96129f1565b5b60006133b888828901612a44565b95505060206133c988828901612a44565b94505060406133da88828901612a7a565b93505060606133eb88828901612a7a565b925050608086013567ffffffffffffffff81111561340c5761340b6129f6565b5b61341888828901612e62565b9150509295509295909350565b60006020828403121561343b5761343a6129f1565b5b600061344984828501612a44565b91505092915050565b7f455243313135353a2061646472657373207a65726f206973206e6f742061207660008201527f616c6964206f776e657200000000000000000000000000000000000000000000602082015250565b60006134ae602a83612bec565b91506134b982613452565b604082019050919050565b600060208201905081810360008301526134dd816134a1565b9050919050565b7f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60008201527f6572206f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613540602e83612bec565b915061354b826134e4565b604082019050919050565b6000602082019050818103600083015261356f81613533565b9050919050565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b60006135d2602983612bec565b91506135dd82613576565b604082019050919050565b60006020820190508181036000830152613601816135c5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061367182612a59565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036136a3576136a2613637565b5b600182019050919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c0000000000815250565b600081905092915050565b60006136ea82612be1565b6136f481856136d4565b9350613704818560208601612bfd565b80840191505092915050565b600061371b826136ae565b601b8201915061372b82846136df565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613792602683612bec565b915061379d82613736565b604082019050919050565b600060208201905081810360008301526137c181613785565b9050919050565b60006137d382612a59565b91506137de83612a59565b92508282019050808211156137f6576137f5613637565b5b92915050565b7f3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323060008201527f30302f73766727207072657365727665417370656374526174696f3d27784d6960208201527f6e594d696e206d656574272076696577426f783d27302030203335302033353060408201527f273e3c726563742077696474683d273130302527206865696768743d2731303060608201527f2527207374796c653d2766696c6c3a0000000000000000000000000000000000608082015250565b60006138ca608f836136d4565b91506138d5826137fc565b608f82019050919050565b7f27202f3e3c7465787420783d273530252720793d273530252720646f6d696e6160008201527f6e742d626173656c696e653d276d6964646c652720746578742d616e63686f7260208201527f3d276d6964646c6527207374796c653d2766696c6c3a00000000000000000000604082015250565b60006139626056836136d4565b915061396d826138e0565b605682019050919050565b7f3b666f6e742d66616d696c793a00000000000000000000000000000000000000815250565b7f3b666f6e742d73697a653a000000000000000000000000000000000000000000815250565b7f70783b0000000000000000000000000000000000000000000000000000000000815250565b7f273e000000000000000000000000000000000000000000000000000000000000815250565b7f3c2f746578743e00000000000000000000000000000000000000000000000000815250565b7f3c2f7376673e0000000000000000000000000000000000000000000000000000815250565b6000613a68828d6136df565b9150613a73826138bd565b9150613a7f828c6136df565b9150613a8a82613955565b9150613a96828b6136df565b9150613aa182613978565b600d82019150613ab1828a6136df565b9150613abc8261399e565b600b82019150613acc82896136df565b9150613ad7826139c4565b600382019150613ae782886136df565b9150613af2826139ea565b600282019150613b0282876136df565b9150613b0d82613a10565b600782019150613b1d82866136df565b9150613b2982856136df565b9150613b3582846136df565b9150613b4082613a36565b6006820191508190509b9a5050505050505050505050565b7f222c20226465736372697074696f6e223a20225468697320697320616e20657860008201527f616d706c65207465737420746f6b656e2c20666f7220747279696e67206f757460208201527f20636f6f6c207468696e67732072656c6174656420746f204e465473203a292060408201527f506c65617365206e6f74652074686174207468697320746f6b656e206861732060608201527f6e6f2076616c7565206f722077617272616e7479206f6620616e79206b696e6460808201527f2e5c6e5c6e5c22546865206675747572652062656c6f6e677320746f2074686f60a08201527f73652077686f2062656c6965766520696e2074686520626561757479206f662060c08201527f746865697220647265616d732e5c225c6e2d456c65616e6f7220526f6f73657660e08201527f656c74222c2022696d6167655f64617461223a2022000000000000000000000061010082015250565b6000613cc0610115836136d4565b9150613ccb82613b58565b61011582019050919050565b7f222c202261747472696275746573223a205b207b2274726169745f747970652260008201527f3a2022546f6b656e204944222c202276616c7565223a20220000000000000000602082015250565b6000613d336038836136d4565b9150613d3e82613cd7565b603882019050919050565b7f227d2c207b2274726169745f74797065223a2022466f6e74222c202276616c7560008201527f65223a2022000000000000000000000000000000000000000000000000000000602082015250565b6000613da56025836136d4565b9150613db082613d49565b602582019050919050565b7f227d2c207b2274726169745f74797065223a2022466f6e742073697a65222c2060008201527f2276616c7565223a202200000000000000000000000000000000000000000000602082015250565b6000613e17602a836136d4565b9150613e2282613dbb565b602a82019050919050565b7f227d2c207b2274726169745f74797065223a202252656374616e676c65222c2060008201527f2276616c7565223a202200000000000000000000000000000000000000000000602082015250565b6000613e89602a836136d4565b9150613e9482613e2d565b602a82019050919050565b7f227d2c207b2274726169745f74797065223a2022547269616e676c65222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b6000613efb6029836136d4565b9150613f0682613e9f565b602982019050919050565b7f227d2c207b2274726169745f74797065223a2022436972636c65222c2022766160008201527f6c7565223a202200000000000000000000000000000000000000000000000000602082015250565b6000613f6d6027836136d4565b9150613f7882613f11565b602782019050919050565b7f227d2c207b2274726169745f74797065223a2022436861696e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b6000613fdf6029836136d4565b9150613fea82613f83565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000815250565b6000614027828d6136df565b9150614033828c6136df565b915061403e82613cb2565b915061404a828b6136df565b915061405582613d26565b9150614061828a6136df565b915061406c82613d98565b915061407882896136df565b915061408382613e0a565b915061408f82886136df565b915061409a82613e7c565b91506140a682876136df565b91506140b182613eee565b91506140bd82866136df565b91506140c882613f60565b91506140d482856136df565b91506140df82613fd2565b91506140eb82846136df565b91506140f682613ff5565b6004820191508190509b9a5050505050505050505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614144602083612bec565b915061414f8261410e565b602082019050919050565b6000602082019050818103600083015261417381614137565b9050919050565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006141d6602183612bec565b91506141e18261417a565b604082019050919050565b60006020820190508181036000830152614205816141c9565b9050919050565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b6000614268602883612bec565b91506142738261420c565b604082019050919050565b600060208201905081810360008301526142978161425b565b9050919050565b600060408201905081810360008301526142b881856131b5565b905081810360208301526142cc81846131b5565b90509392505050565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000614331602583612bec565b915061433c826142d5565b604082019050919050565b6000602082019050818103600083015261436081614324565b9050919050565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b60006143c3602a83612bec565b91506143ce82614367565b604082019050919050565b600060208201905081810360008301526143f2816143b6565b9050919050565b600060408201905061440e6000830185612acf565b61441b6020830184612acf565b9392505050565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b600061447e602983612bec565b915061448982614422565b604082019050919050565b600060208201905081810360008301526144ad81614471565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006144ee82612a59565b91506144f983612a59565b925082614509576145086144b4565b5b828204905092915050565b600061451f82612a59565b915061452a83612a59565b92508261453a576145396144b4565b5b828206905092915050565b7f2720793d27000000000000000000000000000000000000000000000000000000815250565b7f272077696474683d270000000000000000000000000000000000000000000000815250565b7f27206865696768743d2700000000000000000000000000000000000000000000815250565b7f27207374796c653d270000000000000000000000000000000000000000000000815250565b7f27202f3e00000000000000000000000000000000000000000000000000000000815250565b600061460f82896136df565b915061461b82886136df565b915061462682614545565b60058201915061463682876136df565b91506146418261456b565b60098201915061465182866136df565b915061465c82614591565b600a8201915061466c82856136df565b9150614677826145b7565b60098201915061468782846136df565b9150614692826145dd565b600482019150819050979650505050505050565b7f2c00000000000000000000000000000000000000000000000000000000000000815250565b7f2000000000000000000000000000000000000000000000000000000000000000815250565b60006146fe828a6136df565b915061470a82896136df565b9150614715826146a6565b60018201915061472582886136df565b9150614730826146cc565b60018201915061474082876136df565b915061474b826146a6565b60018201915061475b82866136df565b9150614766826146cc565b60018201915061477682856136df565b9150614781826146a6565b60018201915061479182846136df565b915081905098975050505050505050565b60006147ad826145b7565b6009820191506147bd82846136df565b91506147c8826145dd565b60048201915081905092915050565b7f272063793d270000000000000000000000000000000000000000000000000000815250565b7f2720723d27000000000000000000000000000000000000000000000000000000815250565b600061482f82886136df565b915061483b82876136df565b9150614846826147d7565b60068201915061485682866136df565b9150614861826147fd565b60058201915061487182856136df565b915061487c826145b7565b60098201915061488c82846136df565b9150614897826145dd565b6004820191508190509695505050505050565b60006148b582612a59565b91506148c083612a59565b92508282039050818111156148d8576148d7613637565b5b92915050565b7f2c20000000000000000000000000000000000000000000000000000000000000815250565b7f2900000000000000000000000000000000000000000000000000000000000000815250565b600061493682876136df565b915061494282866136df565b915061494d826148de565b60028201915061495d82856136df565b9150614968826148de565b60028201915061497882846136df565b915061498382614904565b60018201915081905095945050505050565b7f3b66696c6c2d6f7061636974793a2e0000000000000000000000000000000000815250565b60006149c782866136df565b91506149d382856136df565b91506149de82614995565b600f820191506149ee82846136df565b9150819050949350505050565b6000614a0682612a59565b9150614a1183612a59565b9250828202614a1f81612a59565b91508282048414831517614a3657614a35613637565b5b5092915050565b7f3b7374726f6b653a000000000000000000000000000000000000000000000000815250565b7f3b7374726f6b652d77696474683a000000000000000000000000000000000000815250565b7f3b7374726f6b652d6f7061636974793a2e000000000000000000000000000000815250565b6000614abb82876136df565b9150614ac682614a3d565b600882019150614ad682866136df565b9150614ae182614a63565b600e82019150614af182856136df565b9150614afc82614a89565b601182019150614b0c82846136df565b915081905095945050505050565b7f3b7374726f6b652d6461736861727261793a0000000000000000000000000000815250565b6000614b4c82856136df565b9150614b5782614b1a565b601282019150614b6782846136df565b91508190509392505050565b600081519050919050565b600082825260208201905092915050565b6000614b9a82614b73565b614ba48185614b7e565b9350614bb4818560208601612bfd565b614bbd81612c27565b840191505092915050565b600060a082019050614bdd60008301886132b8565b614bea60208301876132b8565b8181036040830152614bfc81866131b5565b90508181036060830152614c1081856131b5565b90508181036080830152614c248184614b8f565b90509695505050505050565b600081519050614c3f81612b25565b92915050565b600060208284031215614c5b57614c5a6129f1565b5b6000614c6984828501614c30565b91505092915050565b60008160e01c9050919050565b600060033d1115614c9e5760046000803e614c9b600051614c72565b90505b90565b600060443d10614d2e57614cb36129e7565b60043d036004823e80513d602482011167ffffffffffffffff82111715614cdb575050614d2e565b808201805167ffffffffffffffff811115614cf95750505050614d2e565b80602083010160043d038501811115614d16575050505050614d2e565b614d2582602001850186612cc7565b82955050505050505b90565b7f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b6000614d8d603483612bec565b9150614d9882614d31565b604082019050919050565b60006020820190508181036000830152614dbc81614d80565b9050919050565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b6000614e1f602883612bec565b9150614e2a82614dc3565b604082019050919050565b60006020820190508181036000830152614e4e81614e12565b9050919050565b600060a082019050614e6a60008301886132b8565b614e7760208301876132b8565b614e846040830186612acf565b614e916060830185612acf565b8181036080830152614ea38184614b8f565b9050969550505050505056fe7b226e616d65223a2022417274546f6b656e2d2031313535222c226465736372697074696f6e223a2241207465737420746f6b656e227da2646970667358221220480ac12584fa806339183b621b35a39461fb097ce4a728cc8378e87ed866bbb564736f6c63430008120033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100e95760003560e01c8063731133e91161008c578063e8a3d48511610066578063e8a3d48514610246578063e985e9c514610264578063f242432a14610294578063f2fde38b146102b0576100e9565b8063731133e9146101f05780638da5cb5b1461020c578063a22cb4651461022a576100e9565b80631f7fdffa116100c85780631f7fdffa1461017e5780632eb2c2d61461019a5780634e1273f4146101b6578063715018a6146101e6576100e9565b8062fdd58e146100ee57806301ffc9a71461011e5780630e89341c1461014e575b600080fd5b61010860048036038101906101039190612a8f565b6102cc565b6040516101159190612ade565b60405180910390f35b61013860048036038101906101339190612b51565b610394565b6040516101459190612b99565b60405180910390f35b61016860048036038101906101639190612bb4565b610476565b6040516101759190612c71565b60405180910390f35b61019860048036038101906101939190612e90565b610488565b005b6101b460048036038101906101af9190612f4b565b6104a2565b005b6101d060048036038101906101cb91906130dd565b610543565b6040516101dd9190613213565b60405180910390f35b6101ee61065c565b005b61020a60048036038101906102059190613235565b610670565b005b61021461068a565b60405161022191906132c7565b60405180910390f35b610244600480360381019061023f919061330e565b6106b4565b005b61024e6106ca565b60405161025b9190612c71565b60405180910390f35b61027e6004803603810190610279919061334e565b61070f565b60405161028b9190612b99565b60405180910390f35b6102ae60048036038101906102a9919061338e565b6107a3565b005b6102ca60048036038101906102c59190613425565b610844565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361033c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610333906134c4565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061045f57507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b8061046f575061046e826108ea565b5b9050919050565b606061048182610954565b9050919050565b610490610ace565b61049c84848484610b4c565b50505050565b6104aa610d78565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806104f057506104ef856104ea610d78565b61070f565b5b61052f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052690613556565b60405180910390fd5b61053c8585858585610d80565b5050505050565b60608151835114610589576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610580906135e8565b60405180910390fd5b6000835167ffffffffffffffff8111156105a6576105a5612c98565b5b6040519080825280602002602001820160405280156105d45781602001602082028036833780820191505090505b50905060005b8451811015610651576106218582815181106105f9576105f8613608565b5b602002602001015185838151811061061457610613613608565b5b60200260200101516102cc565b82828151811061063457610633613608565b5b6020026020010181815250508061064a90613666565b90506105da565b508091505092915050565b610664610ace565b61066e60006110a1565b565b610678610ace565b61068484848484611167565b50505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6106c66106bf610d78565b8383611317565b5050565b60606000604051806060016040528060378152602001614eb0603791399050806040516020016106fa9190613710565b60405160208183030381529060405291505090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6107ab610d78565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806107f157506107f0856107eb610d78565b61070f565b5b610830576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082790613556565b60405180910390fd5b61083d8585858585611483565b5050505050565b61084c610ace565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b2906137a8565b60405180910390fd5b6108c4816110a1565b50565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60608060006109628461171e565b9050600061096f8561188d565b9050600061097c86611a5e565b90508361098a876001611bab565b6109a160018961099a91906137c8565b6000611bab565b6109aa89611d1e565b6109b38a611fe7565b6109be8b600161205c565b6109c78c61223e565b8989896040516020016109e39a99989796959493929190613a5c565b604051602081830303815290604052935060006040518060400160405280600b81526020017f7b226e616d65223a202223000000000000000000000000000000000000000000815250905080610a388861223e565b86610a428a61223e565b610a4b8b611d1e565b610a548c611fe7565b610a5d8a61230c565b610a668a61230c565b610a6f8a61230c565b610a784661223e565b604051602001610a919a9998979695949392919061401b565b604051602081830303815290604052905080604051602001610ab39190613710565b60405160208183030381529060405295505050505050919050565b610ad6610d78565b73ffffffffffffffffffffffffffffffffffffffff16610af461068a565b73ffffffffffffffffffffffffffffffffffffffff1614610b4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b419061415a565b60405180910390fd5b565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610bbb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb2906141ec565b60405180910390fd5b8151835114610bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bf69061427e565b60405180910390fd5b6000610c09610d78565b9050610c1a81600087878787612390565b60005b8451811015610cd357838181518110610c3957610c38613608565b5b6020026020010151600080878481518110610c5757610c56613608565b5b6020026020010151815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610cb991906137c8565b925050819055508080610ccb90613666565b915050610c1d565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051610d4b92919061429e565b60405180910390a4610d6281600087878787612398565b610d71816000878787876123a0565b5050505050565b600033905090565b8151835114610dc4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dbb9061427e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610e33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2a90614347565b60405180910390fd5b6000610e3d610d78565b9050610e4d818787878787612390565b60005b8451811015610ffe576000858281518110610e6e57610e6d613608565b5b602002602001015190506000858381518110610e8d57610e8c613608565b5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610f2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f25906143d9565b60405180910390fd5b81810360008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610fe391906137c8565b9250508190555050505080610ff790613666565b9050610e50565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161107592919061429e565b60405180910390a461108b818787878787612398565b6110998187878787876123a0565b505050505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036111d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111cd906141ec565b60405180910390fd5b60006111e0610d78565b905060006111ed85612577565b905060006111fa85612577565b905061120b83600089858589612390565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461126a91906137c8565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516112e89291906143f9565b60405180910390a46112ff83600089858589612398565b61130e836000898989896125f1565b50505050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611385576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137c90614494565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516114769190612b99565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036114f2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e990614347565b60405180910390fd5b60006114fc610d78565b9050600061150985612577565b9050600061151685612577565b9050611526838989858589612390565b600080600088815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050858110156115bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115b4906143d9565b60405180910390fd5b85810360008089815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508560008089815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461167291906137c8565b925050819055508773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a6040516116ef9291906143f9565b60405180910390a4611705848a8a86868a612398565b611713848a8a8a8a8a6125f1565b505050505050505050565b606060006004837f0000000000000000000000001e196b7873b8456437309ba3fa748fa6f1602da873ffffffffffffffffffffffffffffffffffffffff1661176691906144e3565b901c905060006003826117799190614514565b146117965760405180602001604052806000815250915050611888565b60006040518060400160405280600981526020017f3c7265637420783d2700000000000000000000000000000000000000000000008152509050600061012d600184901c6117e49190614514565b9050600061012e600285901c6117fa9190614514565b9050600061012f600386901c6118109190614514565b9050600061012f600487901c6118269190614514565b9050846118328561223e565b61183b8561223e565b6118448561223e565b61184d8561223e565b6118588d600361205c565b60405160200161186d96959493929190614603565b60405160208183030381529060405294508496505050505050505b919050565b606060006005837f0000000000000000000000001e196b7873b8456437309ba3fa748fa6f1602da873ffffffffffffffffffffffffffffffffffffffff166118d591906144e3565b901c905060006005826118e89190614514565b146119055760405180602001604052806000815250915050611a59565b60006040518060400160405280601181526020017f3c706f6c79676f6e20706f696e74733d270000000000000000000000000000008152509050600061012d600184901c6119539190614514565b9050600061012e600285901c6119699190614514565b9050600061012f600386901c61197f9190614514565b90506000610130600487901c6119959190614514565b90506000610131600588901c6119ab9190614514565b90506000610132600689901c6119c19190614514565b9050866119cd8761223e565b6119d68761223e565b6119df8761223e565b6119e88761223e565b6119f18761223e565b6119fa8761223e565b604051602001611a1097969594939291906146f2565b6040516020818303038152906040529650611a2c8a600561205c565b604051602001611a3c91906147a2565b604051602081830303815290604052965086985050505050505050505b919050565b606060006006837f0000000000000000000000001e196b7873b8456437309ba3fa748fa6f1602da873ffffffffffffffffffffffffffffffffffffffff16611aa691906144e3565b901c90506000600782611ab99190614514565b14611ad65760405180602001604052806000815250915050611ba6565b60006040518060400160405280600c81526020017f3c636972636c652063783d2700000000000000000000000000000000000000008152509050600061012c600184901c611b249190614514565b9050600061012c600285901c611b3a9190614514565b905060006096600386901c611b4f9190614514565b905083611b5b8461223e565b611b648461223e565b611b6d8461223e565b611b788b600761205c565b604051602001611b8c959493929190614823565b604051602081830303815290604052935083955050505050505b919050565b606060006003847f0000000000000000000000001e196b7873b8456437309ba3fa748fa6f1602da873ffffffffffffffffffffffffffffffffffffffff16611bf391906144e3565b901c905060006040518060400160405280600481526020017f7267622800000000000000000000000000000000000000000000000000000000815250905060006001151585151514611c46576000611c49565b607f5b60ff1690506000818260ff611c5e91906148aa565b600186901c611c6d9190614514565b611c7791906137c8565b90506000828360ff611c8991906148aa565b600287901c611c989190614514565b611ca291906137c8565b90506000838460ff611cb491906148aa565b600388901c611cc39190614514565b611ccd91906137c8565b905084611cd98461223e565b611ce28461223e565b611ceb8461223e565b604051602001611cfe949392919061492a565b604051602081830303815290604052945084965050505050505092915050565b606060006001837f0000000000000000000000001e196b7873b8456437309ba3fa748fa6f1602da873ffffffffffffffffffffffffffffffffffffffff16611d6691906144e3565b901c90506000600d82611d799190614514565b03611dbc576040518060400160405280600b81526020017f436f7572696572204e6577000000000000000000000000000000000000000000815250915050611fe2565b6000600982611dcb9190614514565b03611e0e576040518060400160405280600881526020017f476172616d6f6e64000000000000000000000000000000000000000000000000815250915050611fe2565b6000600882611e1d9190614514565b03611e60576040518060400160405280600681526020017f5461686f6d610000000000000000000000000000000000000000000000000000815250915050611fe2565b6000600782611e6f9190614514565b03611eb2576040518060400160405280600c81526020017f547265627563686574204d530000000000000000000000000000000000000000815250915050611fe2565b6000600682611ec19190614514565b03611f04576040518060400160405280600f81526020017f54696d6573204e657720526f6d616e0000000000000000000000000000000000815250915050611fe2565b6000600582611f139190614514565b03611f56576040518060400160405280600781526020017f47656f7267696100000000000000000000000000000000000000000000000000815250915050611fe2565b6000600482611f659190614514565b03611fa8576040518060400160405280600981526020017f48656c7665746963610000000000000000000000000000000000000000000000815250915050611fe2565b6040518060400160405280600f81526020017f427275736820536372697074204d5400000000000000000000000000000000008152509150505b919050565b606060006002837f0000000000000000000000001e196b7873b8456437309ba3fa748fa6f1602da873ffffffffffffffffffffffffffffffffffffffff1661202f91906144e3565b901c9050612054600c60b4836120459190614514565b61204f91906137c8565b61223e565b915050919050565b606060006040518060400160405280600581526020017f66696c6c3a0000000000000000000000000000000000000000000000000000008152509050806120bb600185876120aa91906137c8565b6120b491906137c8565b6001611bab565b6120e36120de600387896120cf91906137c8565b6120d991906137c8565b6127c8565b61223e565b6040516020016120f5939291906149bb565b6040516020818303038152906040529050600060046003858761211891906137c8565b61212291906149fb565b61212c9190614514565b0361223457806121546005858761214391906137c8565b61214d91906137c8565b6000611bab565b61217c6121776007878961216891906137c8565b61217291906137c8565b612834565b61223e565b6121a461219f6009888a61219091906137c8565b61219a91906137c8565b6127c8565b61223e565b6040516020016121b79493929190614aaf565b60405160208183030381529060405290506000600584866121d891906137c8565b6121e29190614514565b03612233578061221061220b600d86886121fc91906137c8565b61220691906137c8565b612834565b61223e565b604051602001612221929190614b40565b60405160208183030381529060405290505b5b8091505092915050565b60606000600161224d84612894565b01905060008167ffffffffffffffff81111561226c5761226b612c98565b5b6040519080825280601f01601f19166020018201604052801561229e5781602001600182028036833780820191505090505b509050600082602001820190505b600115612301578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816122f5576122f46144b4565b5b049450600085036122ac575b819350505050919050565b60606000825114612352576040518060400160405280600381526020017f5965730000000000000000000000000000000000000000000000000000000000815250612389565b6040518060400160405280600281526020017f4e6f0000000000000000000000000000000000000000000000000000000000008152505b9050919050565b505050505050565b505050505050565b6123bf8473ffffffffffffffffffffffffffffffffffffffff166108c7565b1561256f578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b8152600401612405959493929190614bc8565b6020604051808303816000875af192505050801561244157506040513d601f19601f8201168201806040525081019061243e9190614c45565b60015b6124e65761244d614c7f565b806308c379a0036124a95750612461614ca1565b8061246c57506124ab565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124a09190612c71565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124dd90614da3565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461256d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256490614e35565b60405180910390fd5b505b505050505050565b60606000600167ffffffffffffffff81111561259657612595612c98565b5b6040519080825280602002602001820160405280156125c45781602001602082028036833780820191505090505b50905082816000815181106125dc576125db613608565b5b60200260200101818152505080915050919050565b6126108473ffffffffffffffffffffffffffffffffffffffff166108c7565b156127c0578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401612656959493929190614e55565b6020604051808303816000875af192505050801561269257506040513d601f19601f8201168201806040525081019061268f9190614c45565b60015b6127375761269e614c7f565b806308c379a0036126fa57506126b2614ca1565b806126bd57506126fc565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f19190612c71565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272e90614da3565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146127be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127b590614e35565b60405180910390fd5b505b505050505050565b6000806003837f0000000000000000000000001e196b7873b8456437309ba3fa748fa6f1602da873ffffffffffffffffffffffffffffffffffffffff1661280f91906144e3565b901c905060016009826128229190614514565b61282c91906137c8565b915050919050565b6000806004837f0000000000000000000000001e196b7873b8456437309ba3fa748fa6f1602da873ffffffffffffffffffffffffffffffffffffffff1661287b91906144e3565b901c9050600a8161288c9190614514565b915050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106128f2577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816128e8576128e76144b4565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061292f576d04ee2d6d415b85acef81000000008381612925576129246144b4565b5b0492506020810190505b662386f26fc10000831061295e57662386f26fc100008381612954576129536144b4565b5b0492506010810190505b6305f5e1008310612987576305f5e100838161297d5761297c6144b4565b5b0492506008810190505b61271083106129ac5761271083816129a2576129a16144b4565b5b0492506004810190505b606483106129cf57606483816129c5576129c46144b4565b5b0492506002810190505b600a83106129de576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612a26826129fb565b9050919050565b612a3681612a1b565b8114612a4157600080fd5b50565b600081359050612a5381612a2d565b92915050565b6000819050919050565b612a6c81612a59565b8114612a7757600080fd5b50565b600081359050612a8981612a63565b92915050565b60008060408385031215612aa657612aa56129f1565b5b6000612ab485828601612a44565b9250506020612ac585828601612a7a565b9150509250929050565b612ad881612a59565b82525050565b6000602082019050612af36000830184612acf565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b2e81612af9565b8114612b3957600080fd5b50565b600081359050612b4b81612b25565b92915050565b600060208284031215612b6757612b666129f1565b5b6000612b7584828501612b3c565b91505092915050565b60008115159050919050565b612b9381612b7e565b82525050565b6000602082019050612bae6000830184612b8a565b92915050565b600060208284031215612bca57612bc96129f1565b5b6000612bd884828501612a7a565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612c1b578082015181840152602081019050612c00565b60008484015250505050565b6000601f19601f8301169050919050565b6000612c4382612be1565b612c4d8185612bec565b9350612c5d818560208601612bfd565b612c6681612c27565b840191505092915050565b60006020820190508181036000830152612c8b8184612c38565b905092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cd082612c27565b810181811067ffffffffffffffff82111715612cef57612cee612c98565b5b80604052505050565b6000612d026129e7565b9050612d0e8282612cc7565b919050565b600067ffffffffffffffff821115612d2e57612d2d612c98565b5b602082029050602081019050919050565b600080fd5b6000612d57612d5284612d13565b612cf8565b90508083825260208201905060208402830185811115612d7a57612d79612d3f565b5b835b81811015612da35780612d8f8882612a7a565b845260208401935050602081019050612d7c565b5050509392505050565b600082601f830112612dc257612dc1612c93565b5b8135612dd2848260208601612d44565b91505092915050565b600080fd5b600067ffffffffffffffff821115612dfb57612dfa612c98565b5b612e0482612c27565b9050602081019050919050565b82818337600083830152505050565b6000612e33612e2e84612de0565b612cf8565b905082815260208101848484011115612e4f57612e4e612ddb565b5b612e5a848285612e11565b509392505050565b600082601f830112612e7757612e76612c93565b5b8135612e87848260208601612e20565b91505092915050565b60008060008060808587031215612eaa57612ea96129f1565b5b6000612eb887828801612a44565b945050602085013567ffffffffffffffff811115612ed957612ed86129f6565b5b612ee587828801612dad565b935050604085013567ffffffffffffffff811115612f0657612f056129f6565b5b612f1287828801612dad565b925050606085013567ffffffffffffffff811115612f3357612f326129f6565b5b612f3f87828801612e62565b91505092959194509250565b600080600080600060a08688031215612f6757612f666129f1565b5b6000612f7588828901612a44565b9550506020612f8688828901612a44565b945050604086013567ffffffffffffffff811115612fa757612fa66129f6565b5b612fb388828901612dad565b935050606086013567ffffffffffffffff811115612fd457612fd36129f6565b5b612fe088828901612dad565b925050608086013567ffffffffffffffff811115613001576130006129f6565b5b61300d88828901612e62565b9150509295509295909350565b600067ffffffffffffffff82111561303557613034612c98565b5b602082029050602081019050919050565b60006130596130548461301a565b612cf8565b9050808382526020820190506020840283018581111561307c5761307b612d3f565b5b835b818110156130a557806130918882612a44565b84526020840193505060208101905061307e565b5050509392505050565b600082601f8301126130c4576130c3612c93565b5b81356130d4848260208601613046565b91505092915050565b600080604083850312156130f4576130f36129f1565b5b600083013567ffffffffffffffff811115613112576131116129f6565b5b61311e858286016130af565b925050602083013567ffffffffffffffff81111561313f5761313e6129f6565b5b61314b85828601612dad565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61318a81612a59565b82525050565b600061319c8383613181565b60208301905092915050565b6000602082019050919050565b60006131c082613155565b6131ca8185613160565b93506131d583613171565b8060005b838110156132065781516131ed8882613190565b97506131f8836131a8565b9250506001810190506131d9565b5085935050505092915050565b6000602082019050818103600083015261322d81846131b5565b905092915050565b6000806000806080858703121561324f5761324e6129f1565b5b600061325d87828801612a44565b945050602061326e87828801612a7a565b935050604061327f87828801612a7a565b925050606085013567ffffffffffffffff8111156132a05761329f6129f6565b5b6132ac87828801612e62565b91505092959194509250565b6132c181612a1b565b82525050565b60006020820190506132dc60008301846132b8565b92915050565b6132eb81612b7e565b81146132f657600080fd5b50565b600081359050613308816132e2565b92915050565b60008060408385031215613325576133246129f1565b5b600061333385828601612a44565b9250506020613344858286016132f9565b9150509250929050565b60008060408385031215613365576133646129f1565b5b600061337385828601612a44565b925050602061338485828601612a44565b9150509250929050565b600080600080600060a086880312156133aa576133a96129f1565b5b60006133b888828901612a44565b95505060206133c988828901612a44565b94505060406133da88828901612a7a565b93505060606133eb88828901612a7a565b925050608086013567ffffffffffffffff81111561340c5761340b6129f6565b5b61341888828901612e62565b9150509295509295909350565b60006020828403121561343b5761343a6129f1565b5b600061344984828501612a44565b91505092915050565b7f455243313135353a2061646472657373207a65726f206973206e6f742061207660008201527f616c6964206f776e657200000000000000000000000000000000000000000000602082015250565b60006134ae602a83612bec565b91506134b982613452565b604082019050919050565b600060208201905081810360008301526134dd816134a1565b9050919050565b7f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60008201527f6572206f7220617070726f766564000000000000000000000000000000000000602082015250565b6000613540602e83612bec565b915061354b826134e4565b604082019050919050565b6000602082019050818103600083015261356f81613533565b9050919050565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b60006135d2602983612bec565b91506135dd82613576565b604082019050919050565b60006020820190508181036000830152613601816135c5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061367182612a59565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036136a3576136a2613637565b5b600182019050919050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c0000000000815250565b600081905092915050565b60006136ea82612be1565b6136f481856136d4565b9350613704818560208601612bfd565b80840191505092915050565b600061371b826136ae565b601b8201915061372b82846136df565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613792602683612bec565b915061379d82613736565b604082019050919050565b600060208201905081810360008301526137c181613785565b9050919050565b60006137d382612a59565b91506137de83612a59565b92508282019050808211156137f6576137f5613637565b5b92915050565b7f3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323060008201527f30302f73766727207072657365727665417370656374526174696f3d27784d6960208201527f6e594d696e206d656574272076696577426f783d27302030203335302033353060408201527f273e3c726563742077696474683d273130302527206865696768743d2731303060608201527f2527207374796c653d2766696c6c3a0000000000000000000000000000000000608082015250565b60006138ca608f836136d4565b91506138d5826137fc565b608f82019050919050565b7f27202f3e3c7465787420783d273530252720793d273530252720646f6d696e6160008201527f6e742d626173656c696e653d276d6964646c652720746578742d616e63686f7260208201527f3d276d6964646c6527207374796c653d2766696c6c3a00000000000000000000604082015250565b60006139626056836136d4565b915061396d826138e0565b605682019050919050565b7f3b666f6e742d66616d696c793a00000000000000000000000000000000000000815250565b7f3b666f6e742d73697a653a000000000000000000000000000000000000000000815250565b7f70783b0000000000000000000000000000000000000000000000000000000000815250565b7f273e000000000000000000000000000000000000000000000000000000000000815250565b7f3c2f746578743e00000000000000000000000000000000000000000000000000815250565b7f3c2f7376673e0000000000000000000000000000000000000000000000000000815250565b6000613a68828d6136df565b9150613a73826138bd565b9150613a7f828c6136df565b9150613a8a82613955565b9150613a96828b6136df565b9150613aa182613978565b600d82019150613ab1828a6136df565b9150613abc8261399e565b600b82019150613acc82896136df565b9150613ad7826139c4565b600382019150613ae782886136df565b9150613af2826139ea565b600282019150613b0282876136df565b9150613b0d82613a10565b600782019150613b1d82866136df565b9150613b2982856136df565b9150613b3582846136df565b9150613b4082613a36565b6006820191508190509b9a5050505050505050505050565b7f222c20226465736372697074696f6e223a20225468697320697320616e20657860008201527f616d706c65207465737420746f6b656e2c20666f7220747279696e67206f757460208201527f20636f6f6c207468696e67732072656c6174656420746f204e465473203a292060408201527f506c65617365206e6f74652074686174207468697320746f6b656e206861732060608201527f6e6f2076616c7565206f722077617272616e7479206f6620616e79206b696e6460808201527f2e5c6e5c6e5c22546865206675747572652062656c6f6e677320746f2074686f60a08201527f73652077686f2062656c6965766520696e2074686520626561757479206f662060c08201527f746865697220647265616d732e5c225c6e2d456c65616e6f7220526f6f73657660e08201527f656c74222c2022696d6167655f64617461223a2022000000000000000000000061010082015250565b6000613cc0610115836136d4565b9150613ccb82613b58565b61011582019050919050565b7f222c202261747472696275746573223a205b207b2274726169745f747970652260008201527f3a2022546f6b656e204944222c202276616c7565223a20220000000000000000602082015250565b6000613d336038836136d4565b9150613d3e82613cd7565b603882019050919050565b7f227d2c207b2274726169745f74797065223a2022466f6e74222c202276616c7560008201527f65223a2022000000000000000000000000000000000000000000000000000000602082015250565b6000613da56025836136d4565b9150613db082613d49565b602582019050919050565b7f227d2c207b2274726169745f74797065223a2022466f6e742073697a65222c2060008201527f2276616c7565223a202200000000000000000000000000000000000000000000602082015250565b6000613e17602a836136d4565b9150613e2282613dbb565b602a82019050919050565b7f227d2c207b2274726169745f74797065223a202252656374616e676c65222c2060008201527f2276616c7565223a202200000000000000000000000000000000000000000000602082015250565b6000613e89602a836136d4565b9150613e9482613e2d565b602a82019050919050565b7f227d2c207b2274726169745f74797065223a2022547269616e676c65222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b6000613efb6029836136d4565b9150613f0682613e9f565b602982019050919050565b7f227d2c207b2274726169745f74797065223a2022436972636c65222c2022766160008201527f6c7565223a202200000000000000000000000000000000000000000000000000602082015250565b6000613f6d6027836136d4565b9150613f7882613f11565b602782019050919050565b7f227d2c207b2274726169745f74797065223a2022436861696e204944222c202260008201527f76616c7565223a20220000000000000000000000000000000000000000000000602082015250565b6000613fdf6029836136d4565b9150613fea82613f83565b602982019050919050565b7f227d5d7d00000000000000000000000000000000000000000000000000000000815250565b6000614027828d6136df565b9150614033828c6136df565b915061403e82613cb2565b915061404a828b6136df565b915061405582613d26565b9150614061828a6136df565b915061406c82613d98565b915061407882896136df565b915061408382613e0a565b915061408f82886136df565b915061409a82613e7c565b91506140a682876136df565b91506140b182613eee565b91506140bd82866136df565b91506140c882613f60565b91506140d482856136df565b91506140df82613fd2565b91506140eb82846136df565b91506140f682613ff5565b6004820191508190509b9a5050505050505050505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614144602083612bec565b915061414f8261410e565b602082019050919050565b6000602082019050818103600083015261417381614137565b9050919050565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006141d6602183612bec565b91506141e18261417a565b604082019050919050565b60006020820190508181036000830152614205816141c9565b9050919050565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b6000614268602883612bec565b91506142738261420c565b604082019050919050565b600060208201905081810360008301526142978161425b565b9050919050565b600060408201905081810360008301526142b881856131b5565b905081810360208301526142cc81846131b5565b90509392505050565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000614331602583612bec565b915061433c826142d5565b604082019050919050565b6000602082019050818103600083015261436081614324565b9050919050565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b60006143c3602a83612bec565b91506143ce82614367565b604082019050919050565b600060208201905081810360008301526143f2816143b6565b9050919050565b600060408201905061440e6000830185612acf565b61441b6020830184612acf565b9392505050565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b600061447e602983612bec565b915061448982614422565b604082019050919050565b600060208201905081810360008301526144ad81614471565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006144ee82612a59565b91506144f983612a59565b925082614509576145086144b4565b5b828204905092915050565b600061451f82612a59565b915061452a83612a59565b92508261453a576145396144b4565b5b828206905092915050565b7f2720793d27000000000000000000000000000000000000000000000000000000815250565b7f272077696474683d270000000000000000000000000000000000000000000000815250565b7f27206865696768743d2700000000000000000000000000000000000000000000815250565b7f27207374796c653d270000000000000000000000000000000000000000000000815250565b7f27202f3e00000000000000000000000000000000000000000000000000000000815250565b600061460f82896136df565b915061461b82886136df565b915061462682614545565b60058201915061463682876136df565b91506146418261456b565b60098201915061465182866136df565b915061465c82614591565b600a8201915061466c82856136df565b9150614677826145b7565b60098201915061468782846136df565b9150614692826145dd565b600482019150819050979650505050505050565b7f2c00000000000000000000000000000000000000000000000000000000000000815250565b7f2000000000000000000000000000000000000000000000000000000000000000815250565b60006146fe828a6136df565b915061470a82896136df565b9150614715826146a6565b60018201915061472582886136df565b9150614730826146cc565b60018201915061474082876136df565b915061474b826146a6565b60018201915061475b82866136df565b9150614766826146cc565b60018201915061477682856136df565b9150614781826146a6565b60018201915061479182846136df565b915081905098975050505050505050565b60006147ad826145b7565b6009820191506147bd82846136df565b91506147c8826145dd565b60048201915081905092915050565b7f272063793d270000000000000000000000000000000000000000000000000000815250565b7f2720723d27000000000000000000000000000000000000000000000000000000815250565b600061482f82886136df565b915061483b82876136df565b9150614846826147d7565b60068201915061485682866136df565b9150614861826147fd565b60058201915061487182856136df565b915061487c826145b7565b60098201915061488c82846136df565b9150614897826145dd565b6004820191508190509695505050505050565b60006148b582612a59565b91506148c083612a59565b92508282039050818111156148d8576148d7613637565b5b92915050565b7f2c20000000000000000000000000000000000000000000000000000000000000815250565b7f2900000000000000000000000000000000000000000000000000000000000000815250565b600061493682876136df565b915061494282866136df565b915061494d826148de565b60028201915061495d82856136df565b9150614968826148de565b60028201915061497882846136df565b915061498382614904565b60018201915081905095945050505050565b7f3b66696c6c2d6f7061636974793a2e0000000000000000000000000000000000815250565b60006149c782866136df565b91506149d382856136df565b91506149de82614995565b600f820191506149ee82846136df565b9150819050949350505050565b6000614a0682612a59565b9150614a1183612a59565b9250828202614a1f81612a59565b91508282048414831517614a3657614a35613637565b5b5092915050565b7f3b7374726f6b653a000000000000000000000000000000000000000000000000815250565b7f3b7374726f6b652d77696474683a000000000000000000000000000000000000815250565b7f3b7374726f6b652d6f7061636974793a2e000000000000000000000000000000815250565b6000614abb82876136df565b9150614ac682614a3d565b600882019150614ad682866136df565b9150614ae182614a63565b600e82019150614af182856136df565b9150614afc82614a89565b601182019150614b0c82846136df565b915081905095945050505050565b7f3b7374726f6b652d6461736861727261793a0000000000000000000000000000815250565b6000614b4c82856136df565b9150614b5782614b1a565b601282019150614b6782846136df565b91508190509392505050565b600081519050919050565b600082825260208201905092915050565b6000614b9a82614b73565b614ba48185614b7e565b9350614bb4818560208601612bfd565b614bbd81612c27565b840191505092915050565b600060a082019050614bdd60008301886132b8565b614bea60208301876132b8565b8181036040830152614bfc81866131b5565b90508181036060830152614c1081856131b5565b90508181036080830152614c248184614b8f565b90509695505050505050565b600081519050614c3f81612b25565b92915050565b600060208284031215614c5b57614c5a6129f1565b5b6000614c6984828501614c30565b91505092915050565b60008160e01c9050919050565b600060033d1115614c9e5760046000803e614c9b600051614c72565b90505b90565b600060443d10614d2e57614cb36129e7565b60043d036004823e80513d602482011167ffffffffffffffff82111715614cdb575050614d2e565b808201805167ffffffffffffffff811115614cf95750505050614d2e565b80602083010160043d038501811115614d16575050505050614d2e565b614d2582602001850186612cc7565b82955050505050505b90565b7f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b6000614d8d603483612bec565b9150614d9882614d31565b604082019050919050565b60006020820190508181036000830152614dbc81614d80565b9050919050565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b6000614e1f602883612bec565b9150614e2a82614dc3565b604082019050919050565b60006020820190508181036000830152614e4e81614e12565b9050919050565b600060a082019050614e6a60008301886132b8565b614e7760208301876132b8565b614e846040830186612acf565b614e916060830185612acf565b8181036080830152614ea38184614b8f565b9050969550505050505056fe7b226e616d65223a2022417274546f6b656e2d2031313535222c226465736372697074696f6e223a2241207465737420746f6b656e227da2646970667358221220480ac12584fa806339183b621b35a39461fb097ce4a728cc8378e87ed866bbb564736f6c63430008120033
Loading...
Loading
Loading...
Loading
OVERVIEW
A test tokenNet Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.