Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 10 from a total of 10 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Fully Reveal... | 693711 | 5 days ago | IN | 0 ETH | 0.00000535 | ||||
Emit Revealed | 588032 | 6 days ago | IN | 0 ETH | 0.0000039 | ||||
Emit Revealed | 588017 | 6 days ago | IN | 0 ETH | 0.0000039 | ||||
Emit Revealed | 588014 | 6 days ago | IN | 0 ETH | 0.0000039 | ||||
Emit Revealed | 588012 | 6 days ago | IN | 0 ETH | 0.0000039 | ||||
Emit Revealed | 588009 | 6 days ago | IN | 0 ETH | 0.00000561 | ||||
Emit Revealed | 550089 | 7 days ago | IN | 0 ETH | 0.00000528 | ||||
Set Contract Uri | 535239 | 7 days ago | IN | 0 ETH | 0.0000771 | ||||
Set Svg Generato... | 535013 | 7 days ago | IN | 0 ETH | 0.0000042 | ||||
Set Block Hash S... | 534989 | 7 days ago | IN | 0 ETH | 0.00000516 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
534903 | 7 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
FirstsRenderer
Compiler Version
v0.8.27+commit.40a35a09
ZkSolc Version
v1.5.9
Optimization Enabled:
Yes with Mode 3
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* SPDX-License-Identifier: MIT Author: nix.eth */ pragma solidity ^0.8.27; import "@openzeppelin/contracts/utils/Base64.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "./FirstsRendererConfig.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { IRenderer } from "../interfaces/IRenderer.sol"; import { IRenderee } from "../interfaces/IRenderee.sol"; import { IFirstsSvgGenerator } from "./IFirstsSvgGenerator.sol"; import { BlockHashStorage } from "./BlockHashStorage.sol"; contract FirstsRenderer is Ownable, IRenderer{ using Strings for uint256; string private _contractUri; address private _claimsAgent; IRenderer private _unrevealedRenderer; bool public fullyRevealed; IRenderee public renderee; IFirstsSvgGenerator public svgGenerator; BlockHashStorage public blockHashStorage; function _spacingName(Spacing spacing) private pure returns(string memory name) { if (spacing == Spacing.NORMAL) name = "Normal"; if (spacing == Spacing.TIGHT) name = "Tight"; if (spacing == Spacing.COMFORTABLE) name = "Comfortable"; } function _encodingName(Encoding encoding) private pure returns(string memory name) { if (encoding == Encoding.HEX) name = "Hexadecimal"; if (encoding == Encoding.PUNCH) name = "Punch Card"; if (encoding == Encoding.OGHAM) name = "Ogham"; if (encoding == Encoding.HUMAN) name = "Lumon Industries"; if (encoding == Encoding.AUTOGLYPHS) name = "Autoglyphs"; if (encoding == Encoding.ATTIC) name = "Attic"; if (encoding == Encoding.DEV) name = "Dev Hell"; if (encoding == Encoding.WIRE) name = "Morse"; if (encoding == Encoding.NOVEL) name = "Novel"; } function _driftName(Drift drift) private pure returns(string memory name){ if (drift == Drift.RIGHT) name = "Right"; if (drift == Drift.LEFT) name = "Left"; if (drift == Drift.UNCERTAIN) name = "Uncertain"; if (drift == Drift.RANDOM) name = "Random"; } constructor(address renderee_, address owner, address claimsAgent, address unrevealedRenderer) Ownable(owner){ renderee = IRenderee(renderee_); _claimsAgent = claimsAgent; _unrevealedRenderer = IRenderer(unrevealedRenderer); } function setUnrevealedRenderer(address unrevealedRenderer) public onlyOwner { _unrevealedRenderer = IRenderer(unrevealedRenderer); } function setFullyRevealed() public onlyOwner { fullyRevealed = true; renderee.emitBatchMetadataUpdate(0, 999); } function emitRevealed(uint tokenId) public { if (!fullyRevealed) { renderee.emitMetadataUpdate(tokenId); } } function setSvgGenerator(address generator) public onlyOwner { svgGenerator = IFirstsSvgGenerator(generator); } function setBlockHashStorage(address address_) public onlyOwner { blockHashStorage = BlockHashStorage(address_); } function setContractUri(string memory uri) public onlyOwner{ _contractUri = uri; renderee.emitContractURIUpdated(uri); } function contractURI() external view returns (string memory) { return _contractUri; } function tokenURI(uint tokenId) external view returns (string memory) { if(fullyRevealed == false) { if(renderee.ownerOf(tokenId) == _claimsAgent) { return _unrevealedRenderer.tokenURI(tokenId); } } bytes32 hash = blockHashStorage.getBlockHash(tokenId); return _tokenURI(tokenId, hash); } function tokenURIForAnyBlock(uint blockId, bytes32 blockHash) external view returns (string memory) { return _tokenURI(blockId, blockHash); } function _tokenURI(uint tokenId, bytes32 hash) private view returns (string memory) { string memory stringTokenId = tokenId.toString(); OutputConfig memory config = _getOutputConfig(tokenId, hash); string memory base64Svg = Base64.encode(abi.encodePacked(svgGenerator.getSvg(config))); bytes memory traits = abi.encodePacked( '{"trait_type": "Block", "value": "',config.id.toString(),'"},', '{"trait_type": "Encoding", "value": "',_encodingName(config.encoding),'"},', '{"trait_type": "Drift", "value": "',_driftName(config.drift),'"},' ); traits = abi.encodePacked( traits, '{"trait_type": "Speed", "value": "',config.speed.toString(),'"},', '{"trait_type": "Scale", "value": "',config.scale.toString(),'"},', '{"trait_type": "Spacing", "value": "',_spacingName(config.spacing),'"}' ); if (config.corruption > 0) { traits = abi.encodePacked( traits, ',{"trait_type": "Corruption", "value": "',config.corruption.toString(),'"}' ); } if (config.driftIntensity > 0) { traits = abi.encodePacked( traits, ',{"trait_type": "Drift Intensity", "value": "',config.driftIntensity.toString(),'"}' ); } bytes memory data = abi.encodePacked( '{', '"id": "', stringTokenId, '",', '"name": "Block #', stringTokenId, '",', '"description": "This network art was generated on-chain from Abstract Block #',stringTokenId,' as one of the chain\'s first 1,000 NFTs.",', '"artist": "nix.eth",', '"external_url": "https://nix.art",' ); data = abi.encodePacked( data, '"image": "data:image/svg+xml;base64,', base64Svg, '",', '"animation_url": "data:text/html;base64,PCFET0NUWVBFIGh0bWw+PGh0bWwgY2xhc3M9Zml4LXJpZ2h0LWNsaWNrLXNhdmU+PGhlYWQ+PG1ldGEgY2hhcnNldD0idXRmLTgiPjx0aXRsZT5GaXJzdHM8L3RpdGxlPjxzdHlsZT5ib2R5LGh0bWx7bWFyZ2luOjA7cGFkZGluZzowO2hlaWdodDoxMDAlfWh0bWx7YmFja2dyb3VuZC1jb2xvcjojMDAwfWJvZHl7ZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpjZW50ZXI7YWxpZ24taXRlbXM6Y2VudGVyfXN2Z3ttYXgtaGVpZ2h0OjEwMCU7bWF4LXdpZHRoOjEwMCV9PC9zdHlsZT48L2hlYWQ+PGJvZHk+',base64Svg,'",', '"attributes": [', traits, ']}' ); return string( abi.encodePacked( "data:application/json;base64,", Base64.encode(data) ) ); } function getSvg(uint tokenId) external view returns(string memory) { bytes32 hash = blockHashStorage.getBlockHash(tokenId); return _getSvg(tokenId, hash); } function getSvgForAnyBlock(uint blockId, bytes32 blockHash) public view returns(string memory) { return _getSvg(blockId, blockHash); } function _getSvg(uint tokenId, bytes32 hash) private view returns(string memory) { OutputConfig memory config = _getOutputConfig(tokenId, hash); return svgGenerator.getSvg(config); } function getHtml(uint tokenId) external view returns(string memory) { bytes32 hash = blockHashStorage.getBlockHash(tokenId); return _getHtml(tokenId, hash); } function getHtmlForAnyBlock(uint blockId, bytes32 blockHash) public view returns(string memory) { return _getHtml(blockId, blockHash); } function _getHtml(uint tokenId, bytes32 hash) private view returns(string memory) { OutputConfig memory config = _getOutputConfig(tokenId, hash); return string(abi.encodePacked( '<!DOCTYPE html><html class=fix-right-click-save><title>Block #', tokenId.toString(), '</title><style>body,html{margin:0;padding:0;height:100%}html{background-color:#000}body{display:flex;justify-content:center;align-items:center}svg{max-height:100%;max-width:100%}</style>', svgGenerator.getSvg(config) )); } function getOutputConfig(uint tokenId) public view returns(OutputConfig memory) { bytes32 hash = blockHashStorage.getBlockHash(tokenId); return _getOutputConfig(tokenId, hash); } function getOutputConfigForAnyBlock(uint blockId, bytes32 blockHash) public pure returns(OutputConfig memory) { return _getOutputConfig(blockId, blockHash); } function _getOutputConfig(uint tokenId, bytes32 hash) private pure returns(OutputConfig memory) { OutputConfig memory config; config.id = tokenId; config.hash = hash; config.speed = _deterministicRandomUintForOutput(config, 1, 9); uint randomDriftChance = _deterministicRandomUintForOutput(config, 0, 99); if (randomDriftChance < 10) { //~10% config.drift = Drift.RANDOM; } else { config.drift = Drift(_deterministicRandomUintForOutput(config, 0, uint256(type(Drift).max) - 1)); config.driftIntensity = _deterministicRandomUintForOutput(config, 1, 4); } uint rareEncodingChance = _deterministicRandomUintForOutput(config, 0, 99); if (rareEncodingChance < 3) { //~3% config.encoding = Encoding.OGHAM; } else { config.encoding = Encoding(_deterministicRandomUintForOutput(config, 0, uint256(type(Encoding).max) - 1)); //-1 to account for rare } uint spacingChance = _deterministicRandomUintForOutput(config, 0, 99); if (spacingChance < 70) { //~70% config.spacing = Spacing.NORMAL; } else if (spacingChance < 90) { //~20% config.spacing = Spacing.COMFORTABLE; } else { //~10% config.spacing = Spacing.TIGHT; } uint maxSize = 9; if (config.encoding == Encoding.PUNCH) { maxSize = 4; } else if (config.spacing == Spacing.COMFORTABLE) { maxSize = 6; } config.scale = _deterministicRandomUintForOutput(config, 2, maxSize); if (config.scale < 3 && config.spacing == Spacing.TIGHT) { config.spacing = Spacing.NORMAL; } if (config.scale < 3 && (config.encoding == Encoding.PUNCH || config.encoding == Encoding.OGHAM)) { config.spacing = Spacing.COMFORTABLE; } uint corruptionChance = _deterministicRandomUintForOutput(config, 0, 99); if (config.encoding == Encoding.NOVEL) { corruptionChance = 99; } if (config.encoding == Encoding.PUNCH || corruptionChance < 40) { //~40% except punchcard config.corruption = 0; } else { config.corruption = _deterministicRandomUintForOutput(config, 1, 20); } return config; } function _deterministicRandomUintForOutput(OutputConfig memory config, uint256 min, uint256 max) private pure returns (uint256) { bytes32 combinedHash = keccak256(abi.encodePacked(config.hash, config.randomStep++)); uint256 randomUint = uint256(combinedHash); uint256 scaledRandom = randomUint % (max - min + 1) + min; return scaledRandom; } }
/* SPDX-License-Identifier: MIT Author: nix.eth */ pragma solidity ^0.8.27; struct OutputConfig { uint id; bytes32 hash; Encoding encoding; Drift drift; uint driftIntensity; uint speed; uint scale; uint corruption; Spacing spacing; uint randomStep; } enum Encoding { NOVEL, PUNCH, HEX, AUTOGLYPHS, ATTIC, DEV, WIRE, HUMAN, OGHAM } enum Drift { UNCERTAIN, LEFT, RIGHT, RANDOM } enum Spacing { NORMAL, TIGHT, COMFORTABLE }
/* SPDX-License-Identifier: MMIITT Author: nix.eth */ pragma solidity ^0.8.27; interface IRenderer { function tokenURI(uint256 tokenId) external view returns (string memory); function contractURI() external view returns (string memory); }
/* SPDX-License-Identifier: MMIITT Author: nix.eth */ pragma solidity ^0.8.27; interface IRenderee { function emitMetadataUpdate(uint tokenId) external; function emitBatchMetadataUpdate(uint fromTokenId, uint toTokenId) external; function emitContractURIUpdated(string memory newContractURI) external; function ownerOf(uint256 tokenId) external view returns (address); }
/* SPDX-License-Identifier: MMIITT Author: nix.eth */ pragma solidity ^0.8.27; import "./FirstsRendererConfig.sol"; interface IFirstsSvgGenerator { function getSvg(OutputConfig memory config) external view returns (string memory); }
/* SPDX-License-Identifier: MIT Author: nix.eth */ pragma solidity ^0.8.27; import '@openzeppelin/contracts/utils/Base64.sol'; import '@openzeppelin/contracts/utils/Strings.sol'; import './FirstsRendererConfig.sol'; import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; import {IRenderer} from '../interfaces/IRenderer.sol'; import {IRenderee} from '../interfaces/IRenderee.sol'; import {IFirstsSvgGenerator} from './IFirstsSvgGenerator.sol'; contract BlockHashStorage is Ownable { constructor(address owner) Ownable(owner) {} mapping(uint => bytes32) hashes; function setBlockHash(uint blockNumber, bytes32 hash) public onlyOwner { hashes[blockNumber] = hash; } function setBlockHashes( uint[] calldata blockNumbers, bytes32[] calldata newHashes ) public onlyOwner { require( blockNumbers.length == newHashes.length, 'Input arrays must be of equal length' ); for (uint i = 0; i < blockNumbers.length; i++) { hashes[blockNumbers[i]] = newHashes[i]; } } function getBlockHash(uint blockNumber) public view returns (bytes32) { return hashes[blockNumber]; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Base64.sol) pragma solidity ^0.8.20; /** * @dev Provides a set of functions to operate with Base64 strings. */ library Base64 { /** * @dev Base64 Encoding/Decoding Table * See sections 4 and 5 of https://datatracker.ietf.org/doc/html/rfc4648 */ string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; string internal constant _TABLE_URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; /** * @dev Converts a `bytes` to its Bytes64 `string` representation. */ function encode(bytes memory data) internal pure returns (string memory) { return _encode(data, _TABLE, true); } /** * @dev Converts a `bytes` to its Bytes64Url `string` representation. * Output is not padded with `=` as specified in https://www.rfc-editor.org/rfc/rfc4648[rfc4648]. */ function encodeURL(bytes memory data) internal pure returns (string memory) { return _encode(data, _TABLE_URL, false); } /** * @dev Internal table-agnostic conversion */ function _encode(bytes memory data, string memory table, bool withPadding) private pure returns (string memory) { /** * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol */ if (data.length == 0) return ""; // If padding is enabled, the final length should be `bytes` data length divided by 3 rounded up and then // multiplied by 4 so that it leaves room for padding the last chunk // - `data.length + 2` -> Prepare for division rounding up // - `/ 3` -> Number of 3-bytes chunks (rounded up) // - `4 *` -> 4 characters for each chunk // This is equivalent to: 4 * Math.ceil(data.length / 3) // // If padding is disabled, the final length should be `bytes` data length multiplied by 4/3 rounded up as // opposed to when padding is required to fill the last chunk. // - `4 * data.length` -> 4 characters for each chunk // - ` + 2` -> Prepare for division rounding up // - `/ 3` -> Number of 3-bytes chunks (rounded up) // This is equivalent to: Math.ceil((4 * data.length) / 3) uint256 resultLength = withPadding ? 4 * ((data.length + 2) / 3) : (4 * data.length + 2) / 3; string memory result = new string(resultLength); assembly ("memory-safe") { // Prepare the lookup table (skip the first "length" byte) let tablePtr := add(table, 1) // Prepare result pointer, jump over length let resultPtr := add(result, 0x20) let dataPtr := data let endPtr := add(data, mload(data)) // In some cases, the last iteration will read bytes after the end of the data. We cache the value, and // set it to zero to make sure no dirty bytes are read in that section. let afterPtr := add(endPtr, 0x20) let afterCache := mload(afterPtr) mstore(afterPtr, 0x00) // Run over the input, 3 bytes at a time for { } lt(dataPtr, endPtr) { } { // Advance 3 bytes dataPtr := add(dataPtr, 3) let input := mload(dataPtr) // To write each character, shift the 3 byte (24 bits) chunk // 4 times in blocks of 6 bits for each character (18, 12, 6, 0) // and apply logical AND with 0x3F to bitmask the least significant 6 bits. // Use this as an index into the lookup table, mload an entire word // so the desired character is in the least significant byte, and // mstore8 this least significant byte into the result and continue. mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F)))) resultPtr := add(resultPtr, 1) // Advance mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F)))) resultPtr := add(resultPtr, 1) // Advance } // Reset the value that was cached mstore(afterPtr, afterCache) if withPadding { // When data `bytes` is not exactly 3 bytes long // it is padded with `=` characters at the end switch mod(mload(data), 3) case 1 { mstore8(sub(resultPtr, 1), 0x3d) mstore8(sub(resultPtr, 2), 0x3d) } case 2 { mstore8(sub(resultPtr, 1), 0x3d) } } } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; import {SafeCast} from "./SafeCast.sol"; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol) pragma solidity ^0.8.20; import {Panic} from "../Panic.sol"; import {SafeCast} from "./SafeCast.sol"; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * 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²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2²⁵⁶ / 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²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. 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⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // 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²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, 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; } } /** * @dev 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) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 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 + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } }
{ "optimizer": { "enabled": true, "mode": "3" }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "abi" ] } }, "detectMissingLibraries": false, "forceEVMLA": false, "enableEraVMExtensions": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"renderee_","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"claimsAgent","type":"address"},{"internalType":"address","name":"unrevealedRenderer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"blockHashStorage","outputs":[{"internalType":"contract BlockHashStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"emitRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fullyRevealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getHtml","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockId","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"}],"name":"getHtmlForAnyBlock","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOutputConfig","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"enum Encoding","name":"encoding","type":"uint8"},{"internalType":"enum Drift","name":"drift","type":"uint8"},{"internalType":"uint256","name":"driftIntensity","type":"uint256"},{"internalType":"uint256","name":"speed","type":"uint256"},{"internalType":"uint256","name":"scale","type":"uint256"},{"internalType":"uint256","name":"corruption","type":"uint256"},{"internalType":"enum Spacing","name":"spacing","type":"uint8"},{"internalType":"uint256","name":"randomStep","type":"uint256"}],"internalType":"struct OutputConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockId","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"}],"name":"getOutputConfigForAnyBlock","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"},{"internalType":"enum Encoding","name":"encoding","type":"uint8"},{"internalType":"enum Drift","name":"drift","type":"uint8"},{"internalType":"uint256","name":"driftIntensity","type":"uint256"},{"internalType":"uint256","name":"speed","type":"uint256"},{"internalType":"uint256","name":"scale","type":"uint256"},{"internalType":"uint256","name":"corruption","type":"uint256"},{"internalType":"enum Spacing","name":"spacing","type":"uint8"},{"internalType":"uint256","name":"randomStep","type":"uint256"}],"internalType":"struct OutputConfig","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSvg","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockId","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"}],"name":"getSvgForAnyBlock","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renderee","outputs":[{"internalType":"contract IRenderee","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"}],"name":"setBlockHashStorage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setContractUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setFullyRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"generator","type":"address"}],"name":"setSvgGenerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"unrevealedRenderer","type":"address"}],"name":"setUnrevealedRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"svgGenerator","outputs":[{"internalType":"contract IFirstsSvgGenerator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockId","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"}],"name":"tokenURIForAnyBlock","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
9c4d535b0000000000000000000000000000000000000000000000000000000000000000010004b3d85b955cd8bc5b2f3c5fb6b477abc5683e9226b469f0b9fcdea6e08b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000080000000000000000000000000f074214f0fa13a06730a2e2052d26d4f66ea2c660000000000000000000000003424cd7d170949636c300e62674a3dfb7706fc35000000000000000000000000680fac6ab3294003574f2214f859dcec719edf01000000000000000000000000f6d3bfd1d94b9c37806666c3736b31af2def06eb
Deployed Bytecode
0x0002000000000002000300000000000200010000000103550000006003100270000004140030019d000004140330019700000001002001900000001f0000c13d0000008004000039000000400040043f000000040030008c000004600000413d000000000201043b000000e0022002700000041c0020009c000000540000213d0000042b0020009c000000a50000a13d0000042c0020009c000000fe0000213d000004300020009c000001a70000613d000004310020009c000001ae0000613d000004320020009c000004600000c13d0000000001000416000000000001004b000004600000c13d0000000501000039000002bb0000013d0000000002000416000000000002004b000004600000c13d0000001f0230003900000415022001970000008002200039000000400020043f0000001f0430018f00000416053001980000008002500039000000300000613d0000008006000039000000000701034f000000007807043c0000000006860436000000000026004b0000002c0000c13d000000000004004b0000003d0000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000000800030008c000004600000413d000000800400043d000004170040009c000004600000213d000000a00600043d000004170060009c000004600000213d000000c00100043d000300000001001d000004170010009c000004600000213d000000e00100043d000200000001001d000004170010009c000004600000213d000000000006004b0000037f0000c13d0000043b01000041000000000010043f000000040000043f0000043a010000410000101b000104300000041d0020009c000000ba0000a13d0000041e0020009c000001090000213d000004220020009c000001b50000613d000004230020009c000002530000613d000004240020009c000004600000c13d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000401100370000000000301043b000001c001000039000000400010043f000000800000043f000000a00000043f000000c00000043f000000e00000043f000001000000043f000001200000043f000001400000043f000001600000043f000001800000043f000001a00000043f0000000601000039000000000101041a0000044402000041000001c00020043f000300000003001d000001c40030043f00000000030004140000041702100197000004140030009c0000041403008041000000c00130021000000445011001c7101910140000040f000001c00a00003900000060031002700000041403300197000000200030008c000000200400003900000000040340190000001f0640018f0000002007400190000001c0057001bf0000008d0000613d000000000801034f000000008908043c000000000a9a043600000000005a004b000000890000c13d000000000006004b0000009a0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000003aa0000613d0000001f01400039000000600110018f000001c001100039000000400010043f000000200030008c000004600000413d000001c00200043d0000000301000029000003700000013d000004330020009c0000012b0000a13d000004340020009c000002b70000613d000004350020009c000002bd0000613d000004360020009c000004600000c13d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000401100370000000000101043b000300000001001d000004170010009c000004600000213d1019065c0000040f0000000501000039000002d60000013d000004250020009c000001680000a13d000004260020009c000002ca0000613d000004270020009c000002dc0000613d000004280020009c000004600000c13d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000602000039000000000202041a0000000401100370000000000301043b0000044401000041000000800010043f000300000003001d000000840030043f00000000010004140000041702200197000004140010009c0000041401008041000000c0011002100000044d011001c7101910140000040f00000060031002700000041403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf000000e50000613d0000008008000039000000000901034f000000009a09043c0000000008a80436000000000058004b000000e10000c13d000000000006004b000000f20000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000003b60000613d0000001f01400039000000600110018f00000080011001bf000000400010043f000000200030008c000004600000413d000000800200043d000000030100002910190cab0000040f000003610000013d0000042d0020009c000002e70000613d0000042e0020009c000002ff0000613d0000042f0020009c000004600000c13d0000000001000416000000000001004b000004600000c13d0000000601000039000002bb0000013d0000041f0020009c000003070000613d000004200020009c000003470000613d000004210020009c000004600000c13d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000401100370000000000101043b000004170010009c000004600000213d000000000200041a00000417052001970000000003000411000000000035004b000003e30000c13d00000417061001980000004f0000613d0000041801200197000000000161019f000000000010041b0000000001000414000004140010009c0000041401008041000000c00110021000000419011001c70000800d0200003900000003030000390000041a04000041000002fa0000013d000004370020009c0000035b0000613d000004380020009c000004600000c13d000000240030008c000004600000413d0000000001000416000000000001004b000004600000c13d0000000301000039000000000101041a0000044b00100198000002fd0000c13d0000000401000039000000000101041a0000043f0200004100000000002004430000041701100197000300000001001d00000004001004430000000001000414000004140010009c0000041401008041000000c00110021000000440011001c70000800202000039101910140000040f0000000100200190000005060000613d000000000101043b000000000001004b000004600000613d000000400300043d0000045001000041000000000013043500000004010000390000000101100367000000000101043b00000004023000390000000000120435000004140030009c000200000003001d0000041401000041000000000103401900000040011002100000000002000414000004140020009c0000041402008041000000c002200210000000000112019f0000043a011001c700000003020000291019100f0000040f0000000100200190000004000000613d0000000201000029000004510010009c000003410000813d000000400010043f00000000010000190000101a0001042e000004290020009c000003660000613d0000042a0020009c000004600000c13d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000602000039000000000202041a0000000401100370000000000301043b0000044401000041000000800010043f000300000003001d000000840030043f00000000010004140000041702200197000004140010009c0000041401008041000000c0011002100000044d011001c7101910140000040f00000060031002700000041403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf0000018f0000613d0000008008000039000000000901034f000000009a09043c0000000008a80436000000000058004b0000018b0000c13d000000000006004b0000019c0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000003c20000613d0000001f01400039000000600110018f00000080011001bf000000400010043f000000200030008c000004600000413d000000800200043d0000000301000029000003600000013d0000000001000416000000000001004b000004600000c13d0000000001030019101905140000040f101906670000040f000003610000013d0000000001000416000000000001004b000004600000c13d0000000001030019101905140000040f10190cab0000040f000003610000013d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000401100370000000000301043b0000000301000039000000000101041a0000044b00100198000200000003001d0000042b0000c13d000100000001001d0000000401000039000000000101041a0000044c02000041000000800020043f000000840030043f00000000030004140000041702100197000004140030009c0000041403008041000000c0013002100000044d011001c7101910140000040f00000060031002700000041403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf000001dd0000613d0000008008000039000000000901034f000000009a09043c0000000008a80436000000000058004b000001d90000c13d000000000006004b000001ea0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000003f40000613d0000001f01400039000000600110018f00000080021001bf000300000002001d000000400020043f000000200030008c000004600000413d000000800200043d000004170020009c000004600000213d0000000203000039000000000303041a000000000223013f0000041700200198000004290000c13d0000044e020000410000000303000029000000000023043500000084011001bf0000000202000029000000000021043500000040013002100000000002000414000004140020009c0000041402008041000000c002200210000000000112019f0000043a011001c700000001020000290000041702200197101910140000040f00000060031002700000001f0430018f000004160530019700000414033001970000000100200190000004840000613d00000003090000290000000002590019000000000005004b0000021b0000613d000000000601034f0000000007090019000000006806043c0000000007870436000000000027004b000002170000c13d000000000004004b000002280000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f0130003900000415011001970000000002910019000000400020043f000000200030008c000004600000413d00000003010000290000000001010433000004430010009c000004600000213d000000030430002900000003011000290000001f03100039000000000043004b000004600000813d0000000031010434000004430010009c000003410000213d0000001f0510003900000452055001970000003f0550003900000452055001970000000005250019000004430050009c000003410000213d000000400050043f00000000051204360000000006310019000000000046004b000004600000213d000000000001004b000002500000613d000000000400001900000000065400190000000007340019000000000707043300000000007604350000002004400039000000000014004b000002490000413d00000000015100190000000000010435000003620000013d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000402100370000000000402043b000004430040009c000004600000213d0000002302400039000000000032004b000004600000813d0000000405400039000000000251034f000000000202043b000004430020009c000003410000213d0000001f0620003900000452066001970000003f066000390000045206600197000004460060009c000003410000213d0000008006600039000000400060043f000000800020043f00000000042400190000002404400039000000000034004b000004600000213d0000002003500039000000000331034f00000452042001980000001f0520018f000000a0014000390000027d0000613d000000a006000039000000000703034f000000007807043c0000000006860436000000000016004b000002790000c13d000000000005004b0000028a0000613d000000000343034f0000000304500210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000000a0012000390000000000010435000000000100041a00000417021001970000000001000411000000000012004b000003a50000c13d000000800200043d000004430020009c000003410000213d0000000101000039000000000301041a000000010430019000000001033002700000007f0330618f0000001f0030008c00000000050000390000000105002039000000000054004b000003550000c13d000000200030008c000002af0000413d000000000010043f0000001f042000390000000504400270000004470440009a000000200020008c0000043c040040410000001f033000390000000503300270000004470330009a000000000034004b000002af0000813d000000000004041b0000000104400039000000000034004b000002ab0000413d0000001f0020008c0000049c0000a13d000000000010043f0000045204200198000004a70000c13d000000a0050000390000043c03000041000004b50000013d0000000001000416000000000001004b000004600000c13d0000000401000039000000000101041a000003030000013d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000401100370000000000101043b000300000001001d000004170010009c000004600000213d1019065c0000040f0000000301000039000002d60000013d000000240030008c000004600000413d0000000002000416000000000002004b000004600000c13d0000000401100370000000000101043b000300000001001d000004170010009c000004600000213d1019065c0000040f0000000601000039000000000201041a000004180220019700000003022001af000000000021041b00000000010000190000101a0001042e0000000001000416000000000001004b000004600000c13d0000000301000039000000000101041a0000044b001001980000000001000039000000010100c039000000800010043f0000044f010000410000101a0001042e0000000001000416000000000001004b000004600000c13d000000000100041a00000417051001970000000002000411000000000025004b000003ce0000c13d0000041801100197000000000010041b0000000001000414000004140010009c0000041401008041000000c00110021000000419011001c70000800d0200003900000003030000390000041a0400004100000000060000191019100f0000040f0000000100200190000004600000613d00000000010000190000101a0001042e0000000001000416000000000001004b000004600000c13d000000000100041a0000041701100197000000800010043f0000044f010000410000101a0001042e0000000001000416000000000001004b000004600000c13d000000000100041a00000417021001970000000001000411000000000012004b000003a50000c13d0000000301000039000000000201041a0000043d022001970000043e022001c7000000000021041b0000000401000039000000000101041a0000043f0200004100000000002004430000041701100197000300000001001d00000004001004430000000001000414000004140010009c0000041401008041000000c00110021000000440011001c70000800202000039101910140000040f0000000100200190000005060000613d000000000101043b000000000001004b000004600000613d000000400300043d0000002401300039000003e70200003900000000002104350000044101000041000000000013043500000004013000390000000000010435000004140030009c000200000003001d0000041401000041000000000103401900000040011002100000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000442011001c700000003020000291019100f0000040f00000001002001900000040d0000613d0000000201000029000004430010009c000005030000a13d0000044a01000041000000000010043f0000004101000039000000040010043f0000043a010000410000101b000104300000000001000416000000000001004b000004600000c13d0000000103000039000000000203041a000000010520019000000001012002700000007f0110618f0000001f0010008c00000000060000390000000106002039000000000662013f0000000100600190000003d30000613d0000044a01000041000000000010043f0000002201000039000000040010043f0000043a010000410000101b000104300000000001000416000000000001004b000004600000c13d0000000001030019101905140000040f101905980000040f0000000002010019000000400100043d000300000001001d101905200000040f000003750000013d0000000001000416000000000001004b000004600000c13d0000000001030019101905140000040f000300000001001d000200000002001d101905790000040f0000000301000029000000020200002910190dff0000040f0000000002010019000000400100043d000300000001001d101905350000040f00000003020000290000000001210049000004140010009c00000414010080410000006001100210000004140020009c00000414020080410000004002200210000000000121019f0000101a0001042e000000000100041a0000041802100197000000000262019f000000000020041b00000000020004140000041705100197000004140020009c0000041402008041000000c00120021000000419011001c70000800d020000390000000303000039000100000004001d0000041a040000411019100f0000040f00000001030000290000000100200190000004600000613d0000000401000039000000000201041a0000041802200197000000000232019f000000000021041b0000000201000039000000000201041a000004180220019700000003022001af000000000021041b0000000303000039000000000103041a000004180110019700000002011001af000000000013041b0000002001000039000001000010044300000120000004430000041b010000410000101a0001042e0000043902000041000000000020043f000000040010043f0000043a010000410000101b000104300000001f0530018f0000041606300198000000400200043d00000000046200190000046d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000003b10000c13d0000046d0000013d0000001f0530018f0000041606300198000000400200043d00000000046200190000046d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000003bd0000c13d0000046d0000013d0000001f0530018f0000041606300198000000400200043d00000000046200190000046d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000003c90000c13d0000046d0000013d0000043901000041000000000010043f000000040020043f0000043a010000410000101b00010430000000800010043f000000000005004b000003e80000613d000000000030043f000000000001004b000003ed0000613d0000043c020000410000000003000019000000000502041a000000a004300039000000000054043500000001022000390000002003300039000000000013004b000003db0000413d000003ed0000013d0000043901000041000000000010043f000000040030043f0000043a010000410000101b000104300000045302200197000000a00020043f000000000001004b000000a0040000390000008004006039000000600240008a0000008001000039101905670000040f000000400100043d000300000001001d0000008002000039000003640000013d0000001f0530018f0000041606300198000000400200043d00000000046200190000046d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000003fb0000c13d0000046d0000013d00000060061002700000001f0460018f0000041605600198000000400200043d0000000003520019000004190000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000004080000c13d000004190000013d00000060061002700000001f0460018f0000041605600198000000400200043d0000000003520019000004190000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b000004150000c13d0000041406600197000000000004004b000004270000613d000000000151034f0000000304400210000000000503043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000013043500000060016002100000047b0000013d00000002030000290000000304000029000300000004001d0000000601000039000000000201041a00000444010000410000000000140435000000040140003900000000003104350000000001000414000004140010009c0000041401008041000000c0011002100000004003400210000000000113019f0000043a011001c70000041702200197101910140000040f000000030b00002900000060031002700000041403300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b00190000044b0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000004470000c13d000000000006004b000004580000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f00000000006504350000000100200190000004620000613d0000001f01400039000000600110018f0000000001b10019000000400010043f000000200030008c000004800000813d00000000010000190000101b000104300000001f0530018f0000041606300198000000400200043d00000000046200190000046d0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000004690000c13d000000000005004b0000047a0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000004140020009c00000414020080410000004002200210000000000112019f0000101b00010430000000030100002900000000020104330000000201000029000001ac0000013d000000400200043d0000000006520019000000000005004b0000048e0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000068004b0000048a0000c13d000000000004004b0000047a0000613d000000000151034f0000000304400210000000000506043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001604350000047a0000013d000000000002004b0000000003000019000004a00000613d000000a00300043d0000000304200210000004540440027f0000045404400167000000000343016f0000000102200210000000000223019f000004c00000013d0000043c030000410000002006000039000000010540008a0000000505500270000004480550009a000000000706001900000080066000390000000006060433000000000063041b00000020067000390000000103300039000000000053004b000004ac0000c13d000000a005700039000000000024004b000004be0000813d0000000304200210000000f80440018f000004540440027f00000454044001670000000005050433000000000445016f000000000043041b000000010220021000000001022001bf000000000021041b0000000401000039000000000101041a0000043f0200004100000000002004430000041701100197000300000001001d00000004001004430000000001000414000004140010009c0000041401008041000000c00110021000000440011001c70000800202000039101910140000040f0000000100200190000005060000613d000000000101043b000000000001004b000004600000613d000000400300043d000004490100004100000000001304350000000401300039000000200200003900000000002104350000002402300039000000800100043d0000000000120435000200000003001d0000004402300039000000000001004b000004e90000613d00000000030000190000000004230019000000a005300039000000000505043300000000005404350000002003300039000000000013004b000004e20000413d0000001f031000390000045203300197000000000121001900000000000104350000004401300039000004140010009c000004140100804100000060011002100000000202000029000004140020009c00000414020080410000004002200210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000003020000291019100f0000040f0000000100200190000005070000613d0000000201000029000004430010009c000003410000213d0000000201000029000000400010043f00000000010000190000101a0001042e000000000001042f00000060061002700000001f0460018f0000041605600198000000400200043d0000000003520019000004190000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000038004b0000050f0000c13d000004190000013d000004550010009c0000051e0000213d000000430010008c0000051e0000a13d00000001020003670000000401200370000000000101043b0000002402200370000000000202043b000000000001042d00000000010000190000101b0001043000000020030000390000000004310436000000003202043400000000002404350000004001100039000000000002004b0000052f0000613d000000000400001900000000051400190000000006430019000000000606043300000000006504350000002004400039000000000024004b000005280000413d000000000312001900000000000304350000001f0220003900000452022001970000000001210019000000000001042d000000004302043400000000033104360000000004040433000000000043043500000040032000390000000003030433000000090030008c000005610000813d0000004004100039000000000034043500000060032000390000000003030433000000030030008c000005610000213d000000600410003900000000003404350000008003200039000000000303043300000080041000390000000000340435000000a0032000390000000003030433000000a0041000390000000000340435000000c0032000390000000003030433000000c0041000390000000000340435000000e003100039000000e0042000390000000004040433000000000043043500000100032000390000000003030433000000020030008c000005610000213d0000010004100039000000000034043500000120022000390000000002020433000001200310003900000000002304350000014001100039000000000001042d0000044a01000041000000000010043f0000002101000039000000040010043f0000043a010000410000101b000104300000001f0220003900000452022001970000000001120019000000000021004b00000000020000390000000102004039000004430010009c000005730000213d0000000100200190000005730000c13d000000400010043f000000000001042d0000044a01000041000000000010043f0000004101000039000000040010043f0000043a010000410000101b00010430000000400100043d000004560010009c000005920000813d0000014002100039000000400020043f0000012002100039000000000002043500000100021000390000000000020435000000e0021000390000000000020435000000c0021000390000000000020435000000a0021000390000000000020435000000800210003900000000000204350000006002100039000000000002043500000040021000390000000000020435000000200210003900000000000204350000000000010435000000000001042d0000044a01000041000000000010043f0000004101000039000000040010043f0000043a010000410000101b00010430000100000000000210190dff0000040f0000000502000039000000000202041a000000400600043d0000045703000041000000000036043500000000430104340000000405600039000000000035043500000000030404330000002404600039000000000034043500000040031000390000000003030433000000090030008c000006330000813d0000004404600039000000000034043500000060031000390000000003030433000000030030008c000006330000213d000000640460003900000000003404350000008003100039000000000303043300000084046000390000000000340435000000a0031000390000000003030433000000a4046000390000000000340435000000c0031000390000000003030433000000c4046000390000000000340435000000e403600039000000e0041000390000000004040433000000000043043500000100031000390000000003030433000000020030008c000006330000213d0000041702200197000001040460003900000000003404350000012001100039000000000101043300000124036000390000000000130435000004140060009c0000041401000041000000000106401900000040011002100000000003000414000004140030009c0000041403008041000000c003300210000000000113019f00000458011001c7000100000006001d101910140000040f00000060031002700000001f0430018f0000041605300197000004140330019700000001002001900000063f0000613d00000001090000290000000002590019000000000005004b000005e80000613d000000000601034f0000000007090019000000006806043c0000000007870436000000000027004b000005e40000c13d000000000004004b000005f50000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f0130003900000415021001970000000001920019000000000021004b00000000020000390000000102004039000004430010009c000006390000213d0000000100200190000006390000c13d000000400010043f0000001f0030008c000006310000a13d0000000002090433000004430020009c000006310000213d000000000493001900000000029200190000001f03200039000000000043004b0000000005000019000004590500804100000459033001970000045906400197000000000763013f000000000063004b00000000030000190000045903004041000004590070009c000000000305c019000000000003004b000006310000c13d0000000032020434000004430020009c000006390000213d0000001f0520003900000452055001970000003f0550003900000452055001970000000005150019000004430050009c000006390000213d000000400050043f00000000052104360000000006320019000000000046004b000006310000213d000000000002004b0000062e0000613d000000000400001900000000065400190000000007340019000000000707043300000000007604350000002004400039000000000024004b000006270000413d00000000025200190000000000020435000000000001042d00000000010000190000101b000104300000044a01000041000000000010043f0000002101000039000000040010043f0000043a010000410000101b000104300000044a01000041000000000010043f0000004101000039000000040010043f0000043a010000410000101b00010430000000400200043d0000000006520019000000000005004b000006490000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000068004b000006450000c13d000000000004004b000006560000613d000000000151034f0000000304400210000000000506043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001604350000006001300210000004140020009c00000414020080410000004002200210000000000112019f0000101b00010430000000000100041a00000417021001970000000001000411000000000012004b000006620000c13d000000000001042d0000043902000041000000000020043f000000040010043f0000043a010000410000101b00010430000b0000000000020000045a0010009c0000066d0000413d00000040030000390000045a0410012a000006760000013d0000045c0010009c00000000040100190000045b0440212a000000000300003900000020030020390000045d0040009c00000010033081bf0000045e044081970000045d0440812a0000045f0040009c000000080330803900000443044081970000045f0440812a000027100040008c00000004033080390000041404408197000027100440811a000000640040008c00000002033080390000ffff0440818f000000640440811a000000090040008c000000010330203900000452043001970000005f054000390000045206500197000000400500043d000a00000005001d0000000005560019000000000065004b00000000060000390000000106004039000004430050009c00000c7a0000213d000000010060019000000c7a0000c13d000000400050043f00000001053000390000000a0a00002900000000095a0436000000200440003900000452054001980000001f0440018f000006a10000613d0000000005590019000000000600003100000001066003670000000007090019000000006806043c0000000007870436000000000057004b0000069d0000c13d000000000004004b000900000009001d00000000033a001900000021033000390000000004010019000000090040008c0000000a5440011a0000000305500210000000010330008a00000000060304330000046006600197000004610550021f0000046205500197000000000565019f0000000000530435000006a60000213d10190dff0000040f0000000502000039000000000202041a000000400600043d0000045703000041000000000036043500000000050100190000000031010434000000040460003900000000001404350000000001030433000000240360003900000000001304350000004001500039000800000001001d0000000001010433000000090010008c00000c800000813d000000440360003900000000001304350000006001500039000600000001001d0000000001010433000000030010008c00000c800000213d0000006403600039000000000013043500000084016000390000008003500039000100000003001d00000000030304330000000000310435000000a401600039000000a003500039000500000003001d00000000030304330000000000310435000000c401600039000000c003500039000400000003001d00000000030304330000000000310435000000e401600039000000e003500039000200000003001d000000000303043300000000003104350000010001500039000300000001001d0000000001010433000000020010008c00000c800000213d000004170220019700000104036000390000000000130435000700000005001d0000012001500039000000000101043300000124036000390000000000130435000004140060009c0000041401000041000000000106401900000040011002100000000003000414000004140030009c0000041403008041000000c003300210000000000113019f00000458011001c7000b00000006001d101910140000040f00000060031002700000001f0430018f00000416053001970000041403300197000000010020019000000c8e0000613d0000000b090000290000000002590019000000000005004b000007090000613d000000000601034f0000000007090019000000006806043c0000000007870436000000000027004b000007050000c13d000000000004004b000000050d000039000007170000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f0130003900000415021001970000000001920019000000000021004b00000000020000390000000102004039000004430010009c00000c7a0000213d000000010020019000000c7a0000c13d000000400010043f0000001f0030008c00000c860000a13d0000000002090433000004430020009c00000c860000213d000000000593001900000000029200190000001f03200039000000000053004b0000000004000019000004590400804100000459033001970000045906500197000000000763013f000000000063004b00000000030000190000045903004041000004590070009c000000000304c019000000000003004b00000c860000c13d0000000042020434000004430020009c00000c7a0000213d0000001f0320003900000452033001970000003f0330003900000452033001970000000003130019000004430030009c00000c7a0000213d000000400030043f00000000032104360000000006420019000000000056004b00000c860000213d000000000002004b000007500000613d000000000500001900000000063500190000000007450019000000000707043300000000007604350000002005500039000000000025004b000007490000413d00000000023200190000000000020435000000400200043d00000020042000390000000001010433000000000001004b0000075f0000613d000000000500001900000000064500190000000007350019000000000707043300000000007604350000002005500039000000000015004b000007580000413d0000000003410019000000000003043500000000001204350000003f0110003900000452011001970000000004210019000000000014004b00000000010000390000000101004039000004430040009c00000c7a0000213d000000010010019000000c7a0000c13d000000400040043f000004630040009c00000c7a0000213d0000006001400039000000400010043f000000400140003900000464030000410000000000310435000000200140003900000465030000410000000000310435000000400100003900000000001404350000000001020433000000000001004b000007ec0000613d000004a70010009c00000c880000813d000004660010009c00000c880000213d0000000201100039000000030110011a0000000203100210000004430030009c00000c7a0000213d0000001f0130003900000452051001970000003f015000390000045206100197000000400100043d0000000006610019000b00000001001d000000000016004b00000000070000390000000107004039000004430060009c00000c7a0000213d000000010070019000000c7a0000c13d000000400060043f0000000b010000290000000003310436000000000005004b000007a00000613d0000000005530019000000000600003100000001066003670000000007030019000000006806043c0000000007870436000000000057004b0000079c0000c13d00000000050204330000000007250019000000200570003900000000060504330000000000050435000000000027004b000007d40000a13d0000000104400039000000000802001900000003088000390000000009080433000000120a9002700000003f0aa0018f000000000a4a0019000000000a0a0433000000f80aa00210000000000b030433000004600bb00197000000000aab019f0000000000a304350000000c0a9002700000003f0aa0018f000000000a4a0019000000000a0a0433000000f80aa00210000000010b300039000000000c0b0433000004600cc00197000000000aac019f0000000000ab0435000000060a9002700000003f0aa0018f000000000a4a0019000000000a0a0433000000f80aa00210000000020b300039000000000c0b0433000004600cc00197000000000aac019f0000000000ab04350000003f0990018f00000000094900190000000009090433000000f809900210000000030a300039000000000b0a0433000004600bb0019700000000099b019f00000000009a04350000000403300039000000000078004b000007a90000413d00000000006504350000000002020433000000032020011a000000020020008c000007f50000613d000000010020008c0000000701000029000007e60000c13d000000010230008a0000000004020433000004600440019700000467044001c70000000000420435000000020230008a0000000003020433000004600330019700000467033001c7000000000032043500000000030104330000045a0030009c000007fe0000413d00000040040000390000045a0230012a000008070000013d000000400100043d000b00000001001d000004680010009c00000c7a0000213d0000000b010000290000002002100039000000400020043f0000000000010435000007fa0000013d000000010230008a0000000003020433000004600330019700000467033001c70000000000320435000000070100002900000000030104330000045a0030009c000007e90000813d0000045c0030009c00000000020300190000045b0220212a000000000400003900000020040020390000045d0020009c00000010044081bf0000045e022081970000045d0220812a0000045f0020009c000000080440803900000443022081970000045f0220812a000027100020008c00000004044080390000041402208197000027100220811a000000640020008c00000002044080390000ffff0220818f000000640220811a000000090020008c000000010440203900000452024001970000005f052000390000045207500197000000400600043d0000000005670019000000000075004b00000000070000390000000107004039000004430050009c00000c7a0000213d000000010070019000000c7a0000c13d000000400050043f00000001054000390000000005560436000000200220003900000452082001980000001f0720018f00000000020000310000000102200367000008310000613d0000000008850019000000000902034f000000000a050019000000009b09043c000000000aba043600000000008a004b0000082d0000c13d000000000007004b00000000044600190000002104400039000000090030008c0000000a7330011a0000000307700210000000010440008a00000000080404330000046008800197000004610770021f0000046207700197000000000787019f0000000000740435000008340000213d00000008010000290000000003010433000000080030008c00000c800000213d000000080030008c000004070003a13e00000060070000390000008008000039000008740000013d00000469030000410000086d0000013d000000400700043d0000046a0070009c00000c7a0000213d00000471030000410000000a0d000039000008700000013d000000400700043d0000046a0070009c00000c7a0000213d00000472030000410000000b0d000039000008700000013d000000400700043d0000046a0070009c00000c7a0000213d0000046e030000410000000a0d000039000008700000013d0000046d030000410000086d0000013d000000400700043d0000046a0070009c00000c7a0000213d0000046c03000041000000080d000039000008700000013d0000046b030000410000086d0000013d000000400700043d0000046a0070009c00000c7a0000213d0000046f03000041000000100d000039000008700000013d0000047003000041000000400700043d0000046a0070009c00000c7a0000213d0000004004700039000000400040043f0000000008d70436000000000038043500000006010000290000000003010433000000030030008c00000c800000213d000000030030008c000004100003a13e0000006009000039000000800a000039000008980000013d000000400900043d0000046a0090009c00000c7a0000213d00000474030000410000000904000039000008940000013d000000400900043d0000046a0090009c00000c7a0000213d00000475030000410000000404000039000008940000013d000000400900043d0000046a0090009c00000c7a0000213d00000476030000410000000504000039000008940000013d000000400900043d0000046a0090009c00000c7a0000213d00000473030000410000000604000039000000400a9000390000004000a0043f000000000a49043600000000003a0435000000400400043d0000004003400039000004770b0000410000000000b304350000002003400039000004780b0000410000000000b30435000000420b4000390000000006060433000000000006004b000008ab0000613d000000000c000019000000000dbc0019000000000e5c0019000000000e0e04330000000000ed0435000000200cc0003900000000006c004b000008a40000413d0000000005b6001900000000000504350000000005460019000000420b500039000004790600004100000000006b0435000000650b5000390000047a0c0000410000000000cb0435000000450b5000390000047b0c0000410000000000cb04350000006a0b5000390000000007070433000000000007004b000008c30000613d000000000c000019000000000dbc0019000000000ec80019000000000e0e04330000000000ed0435000000200cc0003900000000007c004b000008bc0000413d0000000008b70019000000000008043500000000055700190000006a0750003900000000006704350000008d06500039000004770700004100000000007604350000006d065000390000047c0700004100000000007604350000008f0750003900000042055000390000000006090433000000000006004b000008db0000613d00000000080000190000000009780019000000000b8a0019000000000b0b04330000000000b904350000002008800039000000000068004b000008d40000413d0000000007760019000000000007043500000000056500190000004d06500039000004790700004100000000007604350000000005450049000000300650003900000000006404350000006f0550003900000452065001970000000005460019000000000065004b00000000060000390000000106004039000004430050009c00000c7a0000213d000000010060019000000c7a0000c13d000000400050043f000000050100002900000000060104330000045a0060009c000008f60000413d00000040080000390000045a0760012a000008ff0000013d0000045c0060009c00000000070600190000045b0770212a000000000800003900000020080020390000045d0070009c00000010088081bf0000045e077081970000045d0770812a0000045f0070009c000000080880803900000443077081970000045f0770812a000027100070008c00000004088080390000041407708197000027100770811a000000640070008c00000002088080390000ffff0770818f000000640770811a000000090070008c000000010880203900000452098001970000005f0790003900000452077001970000000007570019000004430070009c00000c7a0000213d000000400070043f000000010780003900000000077504360000002009900039000004520a9001980000001f0990018f000009210000613d000000000aa70019000000000b02034f000000000c07001900000000bd0b043c000000000cdc04360000000000ac004b0000091d0000c13d000000000009004b00000000088500190000002108800039000000090060008c0000000a9660011a0000000309900210000000010880008a000000000a080433000004600aa00197000004610990021f00000462099001970000000009a9019f0000000000980435000009240000213d000000040100002900000000060104330000045a0060009c000009360000413d00000040080000390000045a0960012a0000093f0000013d0000045c0060009c00000000090600190000045b0990212a000000000800003900000020080020390000045d0090009c00000010088081bf0000045e099081970000045d0990812a0000045f0090009c000000080880803900000443099081970000045f0990812a000027100090008c00000004088080390000041409908197000027100990811a000000640090008c00000002088080390000ffff0990818f000000640990811a000000090090008c0000000108802039000004520b8001970000005f09b00039000004520c900197000000400a00043d0000000009ac00190000000000c9004b000000000c000039000000010c004039000004430090009c00000c7a0000213d0000000100c0019000000c7a0000c13d000000400090043f000000010980003900000000099a0436000000200bb00039000004520cb001980000001f0bb0018f000009670000613d000000000cc90019000000000d02034f000000000e09001900000000df0d043c000000000efe04360000000000ce004b000009630000c13d00000000000b004b00000000088a00190000002108800039000000090060008c0000000ab660011a000000030bb00210000000010880008a000000000c080433000004600cc00197000004610bb0021f000004620bb00197000000000bcb019f0000000000b804350000096a0000213d00000003010000290000000006010433000000020060008c00000c800000213d000000400b00043d000000010060008c000009830000613d000000000006004b000009880000c13d0000046a00b0009c00000c7a0000213d0000047e0600004100000006080000390000098c0000013d0000046a00b0009c00000c7a0000213d0000047d0600004100000005080000390000098c0000013d0000046a00b0009c00000c7a0000213d0000047f060000410000000b08000039000000400cb000390000004000c0043f000000000c8b043600000000006c0435000000400800043d00000020068000390000000004040433000000000004004b0000099d0000613d000000000d000019000000000e6d0019000000000f3d0019000000000f0f04330000000000fe0435000000200dd0003900000000004d004b000009960000413d000000000364001900000000000304350000000004840019000000400d400039000004770300004100000000003d0435000000200d400039000004800e0000410000000000ed0435000000420d4000390000000005050433000000000005004b000009b20000613d000000000e000019000000000fde001900000000017e0019000000000101043300000000001f0435000000200ee0003900000000005e004b000009ab0000413d0000000001d5001900000000000104350000000001450019000000420510003900000479040000410000000000450435000000650510003900000000003504350000004503100039000004810500004100000000005304350000006707100039000000200310003900000000050a0433000000000005004b000009ca0000613d000000000a00001900000000017a0019000000000d9a0019000000000d0d04330000000000d10435000000200aa0003900000000005a004b000009c30000413d000000000175001900000000000104350000000001530019000000470310003900000000004304350000006a03100039000004820400004100000000004304350000004a03100039000004830400004100000000004304350000006e05100039000000220310003900000000040b0433000000000004004b000009e20000613d0000000007000019000000000157001900000000097c0019000000000909043300000000009104350000002007700039000000000047004b000009db0000413d0000000001540019000000000001043500000000014300190000004c031000390000048404000041000000000043043500000000018100490000002e0310003900000000003804350000006d0110003900000452011001970000000003810019000000000013004b00000000040000390000000104004039000004430030009c00000c7a0000213d000000010040019000000c7a0000c13d000000400030043f00000002010000290000000004010433000000000004004b000009ff0000613d0000045a0040009c00000a020000413d0000045a0540012a000000400700003900000a0b0000013d0000000005060019000000000708001900000a720000013d0000045c0040009c00000000050400190000045b0550212a000000000700003900000020070020390000045d0050009c00000010077081bf0000045e015081970000045d0510812a0000045f0050009c000000080770803900000443015081970000045f0510812a000027100050008c00000004077080390000041401508197000027100510811a000000640050008c00000002077080390000ffff0150818f000000640510811a000000090050008c0000000107702039000000000c07001900000452057001970000005f0150003900000452011001970000000007310019000004430070009c00000c7a0000213d000000400070043f0000000101c000390000000009130436000000200150003900000452071001980000001f0510018f00000a2e0000613d0000000007790019000000000a02034f000000000b09001900000000a10a043c000000000b1b043600000000007b004b00000a2a0000c13d000000000005004b0000000001c300190000002105100039000000090040008c0000000a1440011a0000000301100210000000010550008a00000000070504330000046007700197000004610110021f0000046201100197000000000171019f000000000015043500000a310000213d000000400700043d00000020057000390000000004080433000000000004004b00000a490000613d00000000080000190000000001580019000000000a680019000000000a0a04330000000000a104350000002008800039000000000048004b00000a420000413d00000000015400190000000000010435000000000474001900000040014000390000048506000041000000000061043500000020014000390000048606000041000000000061043500000048064000390000000003030433000000000003004b00000a5e0000613d00000000080000190000000001680019000000000a980019000000000a0a04330000000000a104350000002008800039000000000038004b00000a570000413d00000000016300190000000000010435000000000143001900000048031000390000048404000041000000000043043500000000017100490000002a031000390000000000370435000000690110003900000452011001970000000003710019000000000013004b00000000040000390000000104004039000004430030009c00000c7a0000213d000000010040019000000c7a0000c13d000000400030043f00000001010000290000000004010433000000000004004b000000090c00002900000a7c0000613d0000045a0040009c00000a7e0000413d00000040060000390000045a0840012a00000a870000013d000000000407001900000aee0000013d0000045c0040009c00000000080400190000045b0880212a000000000600003900000020060020390000045d0080009c00000010066081bf0000045e018081970000045d0810812a0000045f0080009c000000080660803900000443018081970000045f0810812a000027100080008c00000004066080390000041401808197000027100810811a000000640080008c00000002066080390000ffff0180818f000000640810811a000000090080008c000000010660203900000452096001970000005f0190003900000452011001970000000008310019000004430080009c00000c7a0000213d000000400080043f000000010160003900000000081304360000002001900039000004520a1001980000001f0910018f00000aa90000613d000000000aa80019000000000b02034f000000000c08001900000000b10b043c000000000c1c04360000000000ac004b00000aa50000c13d000000000009004b00000000016300190000002106100039000000090040008c0000000a1440011a0000000301100210000000010660008a00000000090604330000046009900197000004610110021f0000046201100197000000000191019f000000000016043500000aac0000213d000000400400043d00000020094000390000000006070433000000000006004b00000ac40000613d00000000070000190000000001970019000000000a750019000000000a0a04330000000000a104350000002007700039000000000067004b00000abd0000413d0000000001960019000000000001043500000000054600190000004001500039000004870600004100000000006104350000002001500039000004880600004100000000006104350000004d065000390000000003030433000000000003004b00000ad90000613d000000000700001900000000016700190000000009870019000000000909043300000000009104350000002007700039000000000037004b00000ad20000413d0000000001630019000000000001043500000000015300190000004d031000390000048405000041000000000053043500000000014100490000002f0310003900000000003404350000006e0110003900000452011001970000000003410019000000000013004b00000000050000390000000105004039000004430030009c00000c7a0000213d000000010050019000000c7a0000c13d000000400030043f000000090c0000290000000a0d00002900000020063000390000048901000041000000000016043500000021013000390000048a050000410000000000510435000000280730003900000000050d0433000000000005004b00000b010000613d000000000800001900000000017800190000000009c80019000000000909043300000000009104350000002008800039000000000058004b00000afa0000413d00000000017500190000000000010435000000000535001900000028015000390000048b0700004100000000007104350000002a015000390000048c0800004100000000008104350000003a0950003900000000080d0433000000000008004b00000b160000613d000000000a00001900000000019a0019000000000bca0019000000000b0b04330000000000b10435000000200aa0003900000000008a004b00000b0f0000413d0000000001980019000000000001043500000000015800190000003a0510003900000000007504350000007c051000390000048d0700004100000000007504350000005c051000390000048e0700004100000000007504350000003c051000390000048f0700004100000000007504350000008908100039000000280510003900000000070d0433000000000007004b00000b310000613d00000000090000190000000001890019000000000ac90019000000000a0a04330000000000a104350000002009900039000000000079004b00000b2a0000413d0000000001870019000000000001043500000000017500190000008105100039000004900700004100000000007504350000008b0510003900000491070000410000000000750435000000610510003900000492070000410000000000750435000000bf051000390000048b0700004100000000007504350000009f05100039000004930700004100000000007504350000000001310049000000a10510003900000000005304350000045201100197000000e0011000390000000005310019000000000015004b00000000070000390000000107004039000004430050009c00000c7a0000213d000000010070019000000c7a0000c13d000000400050043f00000020075000390000000003030433000000000003004b00000b5d0000613d000000000800001900000000017800190000000009680019000000000909043300000000009104350000002008800039000000000038004b00000b560000413d0000000001730019000000000001043500000000065300190000004001600039000004940300004100000000003104350000002001600039000004950300004100000000003104350000000b01000029000000200310003900000044086000390000000007010433000000000007004b00000b740000613d00000000090000190000000001890019000000000a390019000000000a0a04330000000000a104350000002009900039000000000079004b00000b6d0000413d00000000018700190000000000010435000000000767001900000044017000390000048b060000410000000000610435000001e60170003900000496080000410000000000810435000001c60170003900000497080000410000000000810435000001a6017000390000049808000041000000000081043500000186017000390000049908000041000000000081043500000166017000390000049a08000041000000000081043500000146017000390000049b08000041000000000081043500000126017000390000049c08000041000000000081043500000106017000390000049d080000410000000000810435000000e6017000390000049e080000410000000000810435000000c6017000390000049f080000410000000000810435000000a601700039000004a00800004100000000008104350000008601700039000004a10800004100000000008104350000006601700039000004a20800004100000000008104350000004601700039000004a3080000410000000000810435000001ee0870003900000020077000390000000b010000290000000001010433000000000001004b00000bb20000613d0000000009000019000000000a890019000000000b390019000000000b0b04330000000000ba04350000002009900039000000000019004b00000bab0000413d000000000381001900000000000304350000000001170019000001ce031000390000000000630435000001d003100039000004a4060000410000000000630435000001df0610003900000024011000390000000043040434000000000003004b00000bc70000613d000000000700001900000000086700190000000009740019000000000909043300000000009804350000002007700039000000000037004b00000bc00000413d000000000463001900000000000404350000000001310019000001bb03100039000004a504000041000000000043043500000000015100490000019d031000390000000000350435000001dc0110003900000452031001970000000001530019000000000031004b00000000030000390000000103004039000004430010009c00000c7a0000213d000000010030019000000c7a0000c13d000000400010043f000004630010009c00000c7a0000213d0000006003100039000000400030043f000000400310003900000464040000410000000000430435000000200310003900000465040000410000000000430435000000400300003900000000003104350000000003050433000000000003004b00000c4e0000613d000004a80030009c00000c880000213d000004660030009c00000c880000213d0000000203300039000000030330011a0000000204300210000004430040009c00000c7a0000213d0000001f0340003900000452063001970000003f036000390000045207300197000000400300043d0000000007730019000000000037004b00000000080000390000000108004039000004430070009c00000c7a0000213d000000010080019000000c7a0000c13d000000400070043f0000000004430436000000000006004b00000c0a0000613d00000000066400190000000007040019000000002802043c0000000007870436000000000067004b00000c060000c13d00000000020504330000000008520019000000200680003900000000070604330000000000060435000000000058004b000000000204001900000c400000a13d0000000101100039000000000905001900000000020400190000000309900039000000000a090433000000120ba002700000003f0bb0018f000000000b1b0019000000000b0b0433000000f80bb00210000000000c020433000004600cc00197000000000bbc019f0000000000b204350000000c0ba002700000003f0bb0018f000000000b1b0019000000000b0b0433000000f80bb00210000000010c200039000000000d0c0433000004600dd00197000000000bbd019f0000000000bc0435000000060ba002700000003f0bb0018f000000000b1b0019000000000b0b0433000000f80bb00210000000020c200039000000000d0c0433000004600dd00197000000000bbd019f0000000000bc04350000003f0aa0018f000000000a1a0019000000000a0a0433000000f80aa00210000000030b200039000000000c0b0433000004600cc00197000000000aac019f0000000000ab04350000000402200039000000000089004b00000c150000413d00000000007604350000000001050433000000031010011a000000020010008c00000c550000613d000000010010008c00000c5a0000c13d000000010120008a0000000005010433000004600550019700000467055001c70000000000510435000000020120008a00000c560000013d000000400300043d000004680030009c00000c7a0000213d0000002004300039000000400040043f000000000003043500000c5a0000013d000000010120008a0000000002010433000004600220019700000467022001c70000000000210435000000400100043d0000002002100039000004a60500004100000000005204350000003d051000390000000002030433000000000002004b00000c6a0000613d000000000300001900000000065300190000000007340019000000000707043300000000007604350000002003300039000000000023004b00000c630000413d000000000352001900000000000304350000001d0320003900000000003104350000005c0220003900000452032001970000000002130019000000000032004b00000000030000390000000103004039000004430020009c00000c7a0000213d000000010030019000000c7a0000c13d000000400020043f000000000001042d0000044a01000041000000000010043f0000004101000039000000040010043f0000043a010000410000101b000104300000044a01000041000000000010043f0000002101000039000000040010043f0000043a010000410000101b0001043000000000010000190000101b000104300000044a01000041000000000010043f0000001101000039000000040010043f0000043a010000410000101b00010430000000400200043d0000000006520019000000000005004b00000c980000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000068004b00000c940000c13d000000000004004b00000ca50000613d000000000151034f0000000304400210000000000506043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001604350000006001300210000004140020009c00000414020080410000004002200210000000000112019f0000101b000104300003000000000002000300000001001d10190dff0000040f000000030a0000290000045a00a0009c00000cb40000413d00000040020000390000045a03a0012a00000cbd0000013d0000045c00a0009c00000000030a00190000045b0330212a000000000200003900000020020020390000045d0030009c00000010022081bf0000045e033081970000045d0330812a0000045f0030009c000000080220803900000443033081970000045f0330812a000027100030008c00000004022080390000041403308197000027100330811a000000640030008c00000002022080390000ffff0330818f000000640330811a000000090030008c000000010220203900000452032001970000005f043000390000045205400197000000400900043d0000000004950019000000000054004b00000000050000390000000105004039000004430040009c00000dd40000213d000000010050019000000dd40000c13d000000400040043f00000001042000390000000008490436000000200330003900000452043001980000001f0330018f00000ce60000613d0000000004480019000000000500003100000001055003670000000006080019000000005705043c0000000006760436000000000046004b00000ce20000c13d000000000003004b000000000229001900000021022000390000000900a0008c0000000a3aa0011a0000000303300210000000010220008a00000000040204330000046004400197000004610330021f0000046203300197000000000343019f000000000032043500000ce90000213d000200000009001d000300000008001d0000000502000039000000000202041a000000400500043d00000457030000410000000000350435000000040350003900000000040104330000000000430435000000200310003900000000030304330000002404500039000000000034043500000040031000390000000003030433000000090030008c00000ddc0000813d0000004404500039000000000034043500000060031000390000000003030433000000030030008c00000ddc0000213d000000640450003900000000003404350000008003100039000000000303043300000084045000390000000000340435000000a0031000390000000003030433000000a4045000390000000000340435000000c0031000390000000003030433000000c4045000390000000000340435000000e403500039000000e0041000390000000004040433000000000043043500000100031000390000000003030433000000020030008c00000ddc0000213d0000041702200197000001040450003900000000003404350000012001100039000000000101043300000124035000390000000000130435000004140050009c0000041401000041000000000105401900000040011002100000000003000414000004140030009c0000041403008041000000c003300210000000000113019f00000458011001c7000100000005001d101910140000040f00000060031002700000001f0430018f00000416053001970000041403300197000000010020019000000de20000613d000000010b00002900000000025b0019000000000005004b00000d450000613d000000000601034f00000000070b0019000000006806043c0000000007870436000000000027004b00000d410000c13d000000000004004b000000030a000029000000020800002900000d540000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f0130003900000415011001970000000002b10019000000000012004b00000000010000390000000101004039000004430020009c00000dd40000213d000000010010019000000dd40000c13d000000400020043f0000001f0030008c00000dda0000a13d00000000010b0433000004430010009c00000dda0000213d0000000005b300190000000001b100190000001f03100039000000000053004b0000000004000019000004590400804100000459033001970000045906500197000000000763013f000000000063004b00000000030000190000045903004041000004590070009c000000000304c019000000000003004b00000dda0000c13d0000000041010434000004430010009c00000dd40000213d0000001f0310003900000452033001970000003f0330003900000452033001970000000003230019000004430030009c00000dd40000213d000000400030043f00000000031204360000000006410019000000000056004b00000dda0000213d000000000001004b00000d8d0000613d000000000500001900000000063500190000000007450019000000000707043300000000007604350000002005500039000000000015004b00000d860000413d00000000013100190000000000010435000000400100043d0000004004100039000004a90500004100000000005404350000002004100039000004aa0500004100000000005404350000005e051000390000000004080433000000000004004b00000da20000613d000000000600001900000000075600190000000008a60019000000000808043300000000008704350000002006600039000000000046004b00000d9b0000413d000000000554001900000000000504350000000005140019000000fe06500039000004ab070000410000000000760435000000de06500039000004ac070000410000000000760435000000be06500039000004ad0700004100000000007604350000009e06500039000004ae0700004100000000007604350000007e06500039000004af0700004100000000007604350000005e06500039000004b007000041000000000076043500000118055000390000000002020433000000000002004b00000dc30000613d000000000600001900000000075600190000000008360019000000000808043300000000008704350000002006600039000000000026004b00000dbc0000413d000000000352001900000000000304350000000002240019000000f8032000390000000000310435000001370220003900000452032001970000000002130019000000000032004b00000000030000390000000103004039000004430020009c00000dd40000213d000000010030019000000dd40000c13d000000400020043f000000000001042d0000044a01000041000000000010043f0000004101000039000000040010043f0000043a010000410000101b0001043000000000010000190000101b000104300000044a01000041000000000010043f0000002101000039000000040010043f0000043a010000410000101b00010430000000400200043d0000000006520019000000000005004b00000dec0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000068004b00000de80000c13d000000000004004b00000df90000613d000000000151034f0000000304400210000000000506043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001604350000006001300210000004140020009c00000414020080410000004002200210000000000112019f0000101b00010430000a000000000002000000400300043d000004560030009c00000ffa0000813d0000014004300039000000400040043f0000012004300039000000000004043500000100043000390000000000040435000000e0043000390000000000040435000000c0043000390000000000040435000000a0043000390000000000040435000000800430003900000000000404350000006004300039000000000004043500000040043000390000000000040435000000200430003900000000000404350000000000030435000000400300043d000700000003001d000004b10030009c00000ffa0000213d00000007040000290000014003400039000000400030043f00000120054000390000000103000039000a00000005001d00000000003504350000000001140436000900000001001d00000000002104350000010001400039000600000001001d0000000000010435000000e001400039000200000001001d0000000000010435000000c001400039000300000001001d0000000000010435000000a001400039000500000001001d00000000000104350000008001400039000100000001001d00000000000104350000006001400039000400000001001d00000000000104350000004001400039000800000001001d00000000000104350000004003000039000000400100043d0000000003310436000000000023043500000040021000390000000000020435000004630010009c00000ffa0000213d0000006002100039000000400020043f000004140030009c000004140300804100000040023002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000091010011a0000000101100039000000050200002900000000001204350000000a040000290000000002040433000000010120003a000010000000613d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000641010011a000000090010008c0000000a0400002900000ed40000a13d0000000002040433000000010120003a000010000000613d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000031010011a000000040200002900000000001204350000000a040000290000000002040433000000010120003a000010000000613d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000030110018f0000000101100039000000010200002900000000001204350000000a0400002900000ed70000013d0000000301000039000000040200002900000000001204350000000002040433000000010120003a000010000000613d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000641010011a000000020010008c0000000a0400002900000f240000a13d0000000002040433000000010120003a000010000000613d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000070110018f0000000a0400002900000f250000013d0000000801000039000000080200002900000000001204350000000002040433000000010120003a000010000000613d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000641010011a000000450010008c0000000a0400002900000f540000a13d000000590010008c000000060300003900000009030020390000000201000039000000010100203900000f560000013d000000090300003900000000010000190000000602000029000000000012043500000008010000290000000001010433000000090010008c000010080000813d000000010010008c00000004030060390000000002040433000000010120003a000010000000613d000500000003001d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d0000000503000029000000010230008a000000020330008a000000000023004b0000000a04000029000010000000213d000000000101043b00000000102100d9000000020210003900000003030000290000000000230435000000000001004b00000fa00000c13d00000006010000290000000001010433000000020010008c000010080000213d000000010010008c00000f960000c13d0000000601000029000000000001043500000008010000290000000001010433000000080010008c000010080000213d00000f9d0000613d000000010010008c00000fa00000c13d0000000201000039000000060200002900000000001204350000000002040433000000010120003a000010000000613d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000641010011a00000008020000290000000002020433000000080020008c0000000a04000029000010080000213d000000000002004b00000fd10000613d000000010020008c000000000200001900000ff60000613d000000270010008c000000000200001900000ff60000a13d0000000002040433000000010120003a000010000000613d000000090300002900000000030304330000000000140435000000400100043d00000040041000390000000000240435000000400200003900000000022104360000000000320435000004630010009c00000ffa0000213d0000006003100039000000400030043f000004140020009c000004140200804100000040022002100000000001010433000004140010009c00000414010080410000006001100210000000000121019f0000000002000414000004140020009c0000041402008041000000c002200210000000000112019f00000419011001c70000801002000039101910140000040f0000000100200190000010060000613d000000000101043b000000141010011a0000000102100039000000020100002900000000002104350000000701000029000000000001042d0000044a01000041000000000010043f0000004101000039000000040010043f0000043a010000410000101b000104300000044a01000041000000000010043f0000001101000039000000040010043f0000043a010000410000101b0001043000000000010000190000101b000104300000044a01000041000000000010043f0000002101000039000000040010043f0000043a010000410000101b00010430000000000001042f00001012002104210000000102000039000000000001042d0000000002000019000000000001042d00001017002104230000000102000039000000000001042d0000000002000019000000000001042d00001019000004320000101a0001042e0000101b000104300000000000000000000000000000000000000000000000000000000000000848000000000000000000000000000000000000000000000000000000000000084a00000000000000000000000000000000000000000000000000000000000008500000000000000000000000000000000000000000000000000000000000000856000000000000000000000000000000000000000000000000000000000000085c000000000000000000000000000000000000000000000000000000000000085e00000000000000000000000000000000000000000000000000000000000008640000000000000000000000000000000000000000000000000000000000000866000000000000000000000000000000000000000000000000000000000000086c000000000000000000000000000000000000000000000000000000000000087d00000000000000000000000000000000000000000000000000000000000008830000000000000000000000000000000000000000000000000000000000000889000000000000000000000000000000000000000000000000000000000000088f00000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000aa1d0a9100000000000000000000000000000000000000000000000000000000c87b56dc00000000000000000000000000000000000000000000000000000000e410b6bc00000000000000000000000000000000000000000000000000000000e410b6bd00000000000000000000000000000000000000000000000000000000e8a3d48500000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000c87b56dd00000000000000000000000000000000000000000000000000000000ccb4807b00000000000000000000000000000000000000000000000000000000d962aa8200000000000000000000000000000000000000000000000000000000bbdfb2d200000000000000000000000000000000000000000000000000000000bbdfb2d300000000000000000000000000000000000000000000000000000000bc31930000000000000000000000000000000000000000000000000000000000c566af1400000000000000000000000000000000000000000000000000000000aa1d0a9200000000000000000000000000000000000000000000000000000000b0dc78fa0000000000000000000000000000000000000000000000000000000048b317b300000000000000000000000000000000000000000000000000000000715018a500000000000000000000000000000000000000000000000000000000715018a6000000000000000000000000000000000000000000000000000000008da5cb5b00000000000000000000000000000000000000000000000000000000989234110000000000000000000000000000000000000000000000000000000048b317b400000000000000000000000000000000000000000000000000000000518bebdb000000000000000000000000000000000000000000000000000000006d6060f5000000000000000000000000000000000000000000000000000000000ce12773000000000000000000000000000000000000000000000000000000000ce12774000000000000000000000000000000000000000000000000000000000d7920db000000000000000000000000000000000000000000000000000000000d8700bb0000000000000000000000000000000000000000000000000000000003f78d680000000000000000000000000000000000000000000000000000000007f76001118cdaa70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000001e4fbdf700000000000000000000000000000000000000000000000000000000b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6ffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff00000000000000000000000100000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b830200000200000000000000000000000000000024000000000000000000000000a4830114000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffee82ac5e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000001c00000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f4ef1d2ad89edf8c4d91132028e8195cdf30bb4b5053d4f8cd260341d4805f30a4ef1d2ad89edf8c4d91132028e8195cdf30bb4b5053d4f8cd260341d4805f3099a6788ea000000000000000000000000000000000000000000000000000000004e487b71000000000000000000000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000006352211e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000800000000000000000c87b56dd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000008000000000000000003190b9ea000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000fffffffffffffec01821cec800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014400000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000000000000000000000000000000000000000004ee2d6d415b85acef810000000000000000000000000000000000000000000004ee2d6d415b85acef80ffffffff000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000ffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000005f5e10000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff30313233343536373839616263646566000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff9f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd3d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffdf4e6f76656c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffbf4d6f7273650000000000000000000000000000000000000000000000000000004465762048656c6c00000000000000000000000000000000000000000000000041747469630000000000000000000000000000000000000000000000000000004175746f676c79706873000000000000000000000000000000000000000000004c756d6f6e20496e6475737472696573000000000000000000000000000000004f6768616d00000000000000000000000000000000000000000000000000000050756e636820436172640000000000000000000000000000000000000000000048657861646563696d616c00000000000000000000000000000000000000000052616e646f6d0000000000000000000000000000000000000000000000000000556e6365727461696e00000000000000000000000000000000000000000000004c65667400000000000000000000000000000000000000000000000000000000526967687400000000000000000000000000000000000000000000000000000020220000000000000000000000000000000000000000000000000000000000007b2274726169745f74797065223a2022426c6f636b222c202276616c7565223a227d2c000000000000000000000000000000000000000000000000000000000065223a20220000000000000000000000000000000000000000000000000000007b2274726169745f74797065223a2022456e636f64696e67222c202276616c757b2274726169745f74797065223a20224472696674222c202276616c7565223a54696768740000000000000000000000000000000000000000000000000000004e6f726d616c0000000000000000000000000000000000000000000000000000436f6d666f727461626c650000000000000000000000000000000000000000007b2274726169745f74797065223a20225370656564222c202276616c7565223a7b2274726169745f74797065223a20225363616c65222c202276616c7565223a223a2022000000000000000000000000000000000000000000000000000000007b2274726169745f74797065223a202253706163696e67222c202276616c7565227d000000000000000000000000000000000000000000000000000000000000616c7565223a20220000000000000000000000000000000000000000000000002c7b2274726169745f74797065223a2022436f7272757074696f6e222c202276222c202276616c7565223a2022000000000000000000000000000000000000002c7b2274726169745f74797065223a2022447269667420496e74656e736974797b00000000000000000000000000000000000000000000000000000000000000226964223a202200000000000000000000000000000000000000000000000000222c000000000000000000000000000000000000000000000000000000000000226e616d65223a2022426c6f636b202300000000000000000000000000000000747261637420426c6f636b202300000000000000000000000000000000000000207761732067656e657261746564206f6e2d636861696e2066726f6d20416273226465736372697074696f6e223a202254686973206e6574776f726b206172743030204e4654732e222c0000000000000000000000000000000000000000000022617274697374223a20226e69782e657468222c000000000000000000000000206173206f6e65206f662074686520636861696e277320666972737420312c302265787465726e616c5f75726c223a202268747470733a2f2f6e69782e6172746536342c0000000000000000000000000000000000000000000000000000000022696d616765223a2022646174613a696d6167652f7376672b786d6c3b62617350474a765a486b2b0000000000000000000000000000000000000000000000005a48526f4f6a45774d4356395043397a64486c735a5434384c32686c5957512b5a33747459586774614756705a3268304f6a45774d435537625746344c5864705a584937595778705a3234746158526c62584d36593256756447567966584e32624756344f327031633352705a6e6b7459323975644756756444706a5a57353062327876636a6f6a4d44417766574a765a486c375a476c7a634778686554706d64446f784d44416c6657683062577837596d466a61326479623356755a43316a625746795a326c754f6a41376347466b5a476c755a7a6f774f32686c6157646f4c3352706447786c506a787a64486c735a543569623252354c47683062577837644430696458526d4c546769506a7830615852735a54354761584a7a64484d384c584e68646d552b5047686c5957512b5047316c6447456759326868636e4e6c625777675932786863334d395a6d6c344c584a705a3268304c574e7361574e723b6261736536342c5043464554304e5557564246494768306257772b5047683022616e696d6174696f6e5f75726c223a2022646174613a746578742f68746d6c2261747472696275746573223a205b00000000000000000000000000000000005d7d000000000000000000000000000000000000000000000000000000000000646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd696768742d636c69636b2d736176653e3c7469746c653e426c6f636b202300003c21444f43545950452068746d6c3e3c68746d6c20636c6173733d6669782d7230253b6d61782d77696474683a313030257d3c2f7374796c653e0000000000006e2d6974656d733a63656e7465727d7376677b6d61782d6865696768743a3130666c65783b6a7573746966792d636f6e74656e743a63656e7465723b616c69676b67726f756e642d636f6c6f723a233030307d626f64797b646973706c61793a303b70616464696e673a303b6865696768743a313030257d68746d6c7b6261633c2f7469746c653e3c7374796c653e626f64792c68746d6c7b6d617267696e3a000000000000000000000000000000000000000000000000fffffffffffffebfe58ac83a2f2be3a9eaac80216846568a964fbde8569109aa146cb431917037ff
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f074214f0fa13a06730a2e2052d26d4f66ea2c660000000000000000000000003424cd7d170949636c300e62674a3dfb7706fc35000000000000000000000000680fac6ab3294003574f2214f859dcec719edf01000000000000000000000000f6d3bfd1d94b9c37806666c3736b31af2def06eb
-----Decoded View---------------
Arg [0] : renderee_ (address): 0xf074214F0fa13A06730a2e2052d26d4f66eA2c66
Arg [1] : owner (address): 0x3424cd7D170949636C300e62674a3DFB7706Fc35
Arg [2] : claimsAgent (address): 0x680faC6ab3294003574f2214f859DCEC719edf01
Arg [3] : unrevealedRenderer (address): 0xf6d3Bfd1d94B9C37806666C3736B31af2def06eB
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f074214f0fa13a06730a2e2052d26d4f66ea2c66
Arg [1] : 0000000000000000000000003424cd7d170949636c300e62674a3dfb7706fc35
Arg [2] : 000000000000000000000000680fac6ab3294003574f2214f859dcec719edf01
Arg [3] : 000000000000000000000000f6d3bfd1d94b9c37806666c3736b31af2def06eb
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.