ETH Price: $3,488.06 (+3.46%)
Gas: 3 Gwei

Contract

0xb119EC7EE48928a94789ed0842309FAF34F0C790
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Set Approval For...201743172024-06-26 7:17:354 days ago1719386255IN
0xb119EC7E...F34F0C790
0 ETH0.000092392
Set Approval For...201451632024-06-22 5:29:119 days ago1719034151IN
0xb119EC7E...F34F0C790
0 ETH0.00009812.1268414
Set Approval For...201373762024-06-21 3:21:3510 days ago1718940095IN
0xb119EC7E...F34F0C790
0 ETH0.000163013.52776461
Set Approval For...201326612024-06-20 11:32:3510 days ago1718883155IN
0xb119EC7E...F34F0C790
0 ETH0.0007009915.14878888
Set Approval For...200600422024-06-10 7:48:4720 days ago1718005727IN
0xb119EC7E...F34F0C790
0 ETH0.000236015.10885687
Set Approval For...199572902024-05-26 23:19:5935 days ago1716765599IN
0xb119EC7E...F34F0C790
0 ETH0.000164473.55939677
Set Approval For...199299802024-05-23 3:44:5939 days ago1716435899IN
0xb119EC7E...F34F0C790
0 ETH0.000210154.55607592
Set Approval For...199131972024-05-20 19:25:1141 days ago1716233111IN
0xb119EC7E...F34F0C790
0 ETH0.0017263137.35794377
Set Approval For...198836312024-05-16 16:07:5945 days ago1715875679IN
0xb119EC7E...F34F0C790
0 ETH0.000307496.66630984
Set Approval For...198334902024-05-09 15:49:4752 days ago1715269787IN
0xb119EC7E...F34F0C790
0 ETH0.000374118.09591794
Set Approval For...198108032024-05-06 11:40:1155 days ago1714995611IN
0xb119EC7E...F34F0C790
0 ETH0.000259925.62491265
Set Approval For...197986282024-05-04 18:47:5957 days ago1714848479IN
0xb119EC7E...F34F0C790
0 ETH0.000210434.56213187
Set Approval For...197951502024-05-04 7:08:3557 days ago1714806515IN
0xb119EC7E...F34F0C790
0 ETH0.000273975.92895392
Set Approval For...197858822024-05-03 0:02:3559 days ago1714694555IN
0xb119EC7E...F34F0C790
0 ETH0.000205914.4641199
Set Approval For...197851102024-05-02 21:26:5959 days ago1714685219IN
0xb119EC7E...F34F0C790
0 ETH0.000288926.25237163
Set Approval For...197798842024-05-02 3:54:1160 days ago1714622051IN
0xb119EC7E...F34F0C790
0 ETH0.000120424.59181575
Set Approval For...197798822024-05-02 3:53:4760 days ago1714622027IN
0xb119EC7E...F34F0C790
0 ETH0.000203484.41159103
Set Approval For...197784862024-05-01 23:11:5960 days ago1714605119IN
0xb119EC7E...F34F0C790
0 ETH0.000208444.51072591
Set Approval For...197289192024-04-25 0:51:2367 days ago1714006283IN
0xb119EC7E...F34F0C790
0 ETH0.000277356.00204003
Safe Transfer Fr...196509142024-04-14 2:51:1178 days ago1713063071IN
0xb119EC7E...F34F0C790
0 ETH0.0025134111.56369991
Set Approval For...195949182024-04-06 6:32:5985 days ago1712385179IN
0xb119EC7E...F34F0C790
0 ETH0.0005735412.41493157
Set Approval For...195860732024-04-05 0:48:5987 days ago1712278139IN
0xb119EC7E...F34F0C790
0 ETH0.0005250811.38374121
Set Approval For...195521462024-03-31 6:37:5991 days ago1711867079IN
0xb119EC7E...F34F0C790
0 ETH0.0010210922.1371399
Set Approval For...195115362024-03-25 12:36:4797 days ago1711370207IN
0xb119EC7E...F34F0C790
0 ETH0.0009577720.72666133
Set Approval For...195088802024-03-25 3:36:5998 days ago1711337819IN
0xb119EC7E...F34F0C790
0 ETH0.0006182813.40424844
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
175157892023-06-19 19:13:11377 days ago1687201991
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
175155542023-06-19 18:25:23377 days ago1687199123
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
175155492023-06-19 18:24:23377 days ago1687199063
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
175155442023-06-19 18:23:23377 days ago1687199003
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172630102023-05-15 5:05:59413 days ago1684127159
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172629542023-05-15 4:54:47413 days ago1684126487
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172629462023-05-15 4:52:59413 days ago1684126379
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172629382023-05-15 4:51:23413 days ago1684126283
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172629302023-05-15 4:49:47413 days ago1684126187
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172629222023-05-15 4:48:11413 days ago1684126091
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172629152023-05-15 4:46:47413 days ago1684126007
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172629072023-05-15 4:45:11413 days ago1684125911
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172629002023-05-15 4:43:47413 days ago1684125827
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628922023-05-15 4:42:11413 days ago1684125731
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628852023-05-15 4:40:47413 days ago1684125647
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628782023-05-15 4:39:23413 days ago1684125563
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628702023-05-15 4:37:47413 days ago1684125467
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628632023-05-15 4:36:23413 days ago1684125383
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628542023-05-15 4:34:35413 days ago1684125275
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628482023-05-15 4:33:23413 days ago1684125203
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628402023-05-15 4:31:47413 days ago1684125107
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628322023-05-15 4:30:11413 days ago1684125011
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628252023-05-15 4:28:47413 days ago1684124927
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172628082023-05-15 4:25:23413 days ago1684124723
0xb119EC7E...F34F0C790
 Contract Creation0 ETH
172627522023-05-15 4:14:11413 days ago1684124051  Contract Creation0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Lawless

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 11 : Lawless.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2023 Ponderware Ltd

pragma solidity ^0.8.17;

import "./lib/LawlessGIF.sol";
import "../lib/TokenizedContract.sol";
import "@openzeppelin/contracts/utils/Create2.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";

interface IDelegationRegistry {
    function checkDelegateForContract(address delegate, address vault, address contract_) external view returns(bool);
    function checkDelegateForToken(address delegate, address vault, address contract_, uint256 tokenId) external view returns (bool);

}

interface ICustomAttributes {
    function getCustomAttributes () external view returns (bytes memory);
}

interface ILawlessMetadata {
    function generateTokenURI (LawlessData memory) external view returns (string memory);
    function setB64EncodeURI (bool value) external;
    function addMetadataMod (address addr) external;
}

type Ex is uint256;

struct Record {
    address owner;
    uint16 index;
    uint16 version;
    uint16 style;
    uint48 details;
}

struct LawlessData {
    uint id;
    uint modelId;
    uint paletteId;
    address owner;
    uint16 version;
    uint48 details;
}

/*
 * @title Lawless
 * @author Ponderware Ltd
 * @notice chain-complete ERC-721 character contract
 */
contract Lawless is TokenizedContract, LawlessGIF {

    string public name = "lawless";
    string public symbol = unicode"🏴";

    constructor (uint256 tokenId) TokenizedContract(tokenId) {
        addRole(owner(), Role.Uploader);
        addRole(owner(), Role.Curator);
        addRole(owner(), Role.Pauser);
        addRole(0xEBFEFB02CaD474D35CabADEbddF0b32D287BE1bd, Role.CodeLawless);
    }

    /* Events */

    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /* Supply */

    uint256 internal constant maxSupply = 8192;
    uint256 internal constant maxSupplyMod = 8191;
    uint256 public totalSupply = 0;

    /* Bookkeeping Data */

    Record[maxSupply] internal Records;
    mapping (address => uint16[maxSupply+1]) internal TokensByOwner; // index 0 is "length"

    modifier validLawlessId (uint id) {
        require(id < totalSupply, "unrecognized lawless");
        _;
    }

    /* Delegation */

    IDelegationRegistry constant dc = IDelegationRegistry(0x00000000000076A84feF008CDAbe6409d2FE638B);

    bool public delegationEnabled = true;

    function smashFlask () public onlyBy(Role.Ponderware) {
        delegationEnabled = false;
    }

    /* Data */

    function uploadModels (uint48 count, bytes memory data) public onlyBy(Role.Uploader) {
        _uploadModels(count, data);
    }

    function uploadPalettes (uint48 count, bytes memory data) public onlyBy(Role.Uploader) {
        _uploadPalettes(count, data);
    }

    /* Metadata */

    ILawlessMetadata Metadata;

    function setMetadata (bytes calldata metadata) public onlyBy(Role.Curator) {
        removeRole(address(Metadata), Role.Metadata);
        Metadata = ILawlessMetadata(Create2.deploy(0, 0, abi.encodePacked(metadata, abi.encode(address(this), CodexAddress))));
        addRole(address(Metadata), Role.Metadata);
    }

    function setB64EncodeURI (bool value) public onlyBy(Role.Curator) {
        Metadata.setB64EncodeURI(value);
    }

    function addMetadataMod (address addr) public onlyBy(Role.Curator) {
        Metadata.addMetadataMod(addr);
    }

    function getModel (uint id) public view onlyBy(Role.Metadata) returns (Model memory) {
        return _getModel(id);
    }

    function getPalette (uint id) public view onlyBy(Role.Metadata) returns (bytes memory) {
        return _getPalette(id);
    }

    function staticGIF (Model memory model, bytes memory palette) public view onlyBy(Role.Metadata) returns (string memory) {
        return _staticGIF(model, palette);
    }

    function animatedGIF (Model memory model, bytes memory palette) public view onlyBy(Role.Metadata) returns (string memory) {
        return _animatedGIF(model, palette);
    }

    function getModelAndPaletteIds (uint style) internal pure returns (uint, uint) {
        return (style >> 5, style & 31);
    }

    function getData (uint id) public view validLawlessId(id) returns (LawlessData memory) {
        Record storage record = Records[id];
        (uint modelId, uint paletteId) = getModelAndPaletteIds(record.style);
        return LawlessData(id, modelId, paletteId, record.owner, record.version, record.details);
    }

    /* Token URI */

    function tokenURI (Ex tokenId) public view returns (string memory) {
        uint id = Ex.unwrap(tokenId) & maxSupplyMod;
        require (Ex.unwrap(tokenId) == (id + Records[id].version * maxSupply), "invalid tokenId");
        return Metadata.generateTokenURI(getData(id));
    }

    /* View Helpers */

    function getTokenId (uint256 id) external view validLawlessId(id) returns (uint) {
        return id + Records[id].version * maxSupply;
    }

    function getLawlessId (Ex tokenId) external view returns (uint id) {
        id = Ex.unwrap(tokenId) & maxSupplyMod;
        require (id < totalSupply && Ex.unwrap(tokenId) == (id + Records[id].version * maxSupply), "invalid tokenId");
    }

    /* Immutable lawless GIF lookups */

    function lawlessGIF (uint256 id, bool base) public view validLawlessId(id) returns (string memory) {
        Record storage record = Records[id];
        (uint modelId, uint paletteId) = getModelAndPaletteIds(record.style);
        uint details = record.details;
        if (!base) {
            uint morph = details >> 24;
            if ((morph & 1024) > 0) {
                modelId = 256 + (morph & 1023);
            }
            uint shift = details >> 12;
            if ((shift & 1024) > 0) {
                paletteId = 32 + (shift & 1023);
            }
        }
        if (details >= 211106232532992 || modelId > 255) {
            return _animatedGIF(_getModel(modelId), _getPalette(paletteId));
        } else {
            return _staticGIF(_getModel(modelId), _getPalette(paletteId));
        }
    }

    function tokenGIF (Ex tokenId, bool base) external view returns (string memory) {
        uint id = Ex.unwrap(tokenId) & maxSupplyMod;
        require (Ex.unwrap(tokenId) == (id + Records[id].version * maxSupply), "invalid tokenId");
        return lawlessGIF(id, base);
    }

    /* Details */

    function _updateId (uint id, address owner) internal {
        uint currentVersion = Records[id].version++;
        uint currentExternalId = id + (currentVersion * totalSupply);
        uint nextExternalId = currentExternalId + maxSupply;
        emit Transfer(owner, address(0), currentExternalId);
        emit Transfer(address(0), owner, nextExternalId);
    }

    function _authorized (uint id, address owner, address operator) internal view returns (bool) {
        return (operator == CodexAddress
                || operator == owner
                || TokenApprovals[id] == operator
                || isApprovedForAll(owner, operator)
                || (delegationEnabled
                    && (dc.checkDelegateForContract(operator, owner, address(this))
                        || dc.checkDelegateForToken(operator, owner, address(this), id))));

    }

    function getDetails (Ex tokenId) external view returns (uint, address, uint48) {
        uint id = Ex.unwrap(tokenId) & maxSupplyMod;
        Record storage record = Records[id];
        require (id < totalSupply && Ex.unwrap(tokenId) == (id + record.version * maxSupply), "invalid tokenId");
        return (id, record.owner, record.details);
    }

    function authorized (address operator, Ex tokenId) external view returns (bool) {
        uint id = Ex.unwrap(tokenId) & maxSupplyMod;
        Record storage record = Records[id];
        require (id < totalSupply && Ex.unwrap(tokenId) == (id + record.version * maxSupply), "invalid tokenId");
        return _authorized(id, record.owner, operator);
    }

    function incrementVersion (address operator, uint id) external validLawlessId(id) onlyBy(Role.Surgeon) {
        Record storage record = Records[id];
        require(_authorized(id, record.owner, operator), "unauthorized");
        _updateId(id, record.owner);
    }

    function updateDetails (address operator, uint id, uint48 details, bool incVersion) external validLawlessId(id) onlyBy(Role.Surgeon) {
        Record storage record = Records[id];
        require(_authorized(id, record.owner, operator), "unauthorized");
        record.details = details;
        if (incVersion) _updateId(id, record.owner);
    }

    /* Minting */

    function handleMint (bytes32 seed, address to, uint48 details) internal {
        uint index = (uint256(seed) % (maxSupply - totalSupply)) + totalSupply;
        Record storage atCursor = Records[totalSupply];
        Record storage atIndex = Records[index];
        uint16 atIndexStyle = atIndex.style;
        if (atCursor.owner == address(0)) {
            atIndex.style = uint16(totalSupply);
        } else {
            atIndex.style = atCursor.style;
        }
        if (atIndex.owner == address(0)) {
            atCursor.style = uint16(index);
        } else {
            atCursor.style = atIndexStyle;
        }

        atIndex.owner = to; // used to check if value has been seen
        atCursor.owner = to;
        atCursor.details = details;

        uint16 setIndex = TokensByOwner[to][0]++;
        atCursor.index = setIndex;
        TokensByOwner[to][setIndex + 1] = uint16(totalSupply);
        emit Transfer(address(0), to, totalSupply);
        totalSupply++;
    }

    function mint (uint256 seed, address to, uint48 details) public onlyBy(Role.Minter) {
        require (totalSupply < maxSupply, "rescue complete");
        handleMint(keccak256(abi.encodePacked(to, seed, totalSupply)), to, details);
    }

    function batchMint (uint256 seed, address[] calldata to, uint48[] calldata details) public onlyBy(Role.Minter) {
        require ((totalSupply + to.length) <= maxSupply, "insufficient supply");
        for (uint i = 0; i < to.length; i++) {
            handleMint(keccak256(abi.encodePacked(to[i], seed, totalSupply, i)), to[i], details[i]);
        }
    }

    /* ERC-165 */

    function supportsInterface(bytes4 interfaceId) public view returns (bool) {

        if (msg.sender == CodexAddress) { // workaround for ERC721 custom metadata
            return
                interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
                interfaceId == type(ICustomAttributes).interfaceId;
        } else {
            return
                interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
                interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
                interfaceId == 0x780E9D63 || // ERC165 Interface ID for ERC721Enumerable
                interfaceId == 0x5b5e139f || // ERC165 Interface ID for ERC721Metadata
                interfaceId == 0x2A55205A || // ERC165 Interface ID for ERC2981
                interfaceId == type(ICustomAttributes).interfaceId;
        }
    }

    /* Custom Attributes */

    function getCustomAttributes () external view returns (bytes memory) {
        string memory mintedPct = toPctString1000x(totalSupply * 1000 / maxSupply);
        return abi.encodePacked(ICodex(CodexAddress).encodeStringAttribute("token type", "ERC-721"),
                                ",",
                                ICodex(CodexAddress).encodeNumericAttribute("total supply", totalSupply),
                                ",",
                                ICodex(CodexAddress).encodeStringAttribute("minted", mintedPct));
    }

    /* ERC-721 Base */

    // Mapping from token ID to approved address
    address[maxSupply] private TokenApprovals;
    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private OperatorApprovals;

    function _transfer (address from, address to, Ex tokenId) private whenNotPaused {
        uint id = Ex.unwrap(tokenId) & maxSupplyMod;  // don't need to check if id < totalSupply because Records lookup will fail
        TokenApprovals[id] = address(0); // Clear approvals from the previous owner
        Record storage record = Records[id];
        require(record.owner == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");
        require(Ex.unwrap(tokenId) == (id + (record.version * maxSupply)), "ERC721: Nonexistent token");
        uint16 valueIndex = record.index + 1;
        uint16 lastIndex = TokensByOwner[from][0]--;
        if (lastIndex != valueIndex) {
            uint16 lastId = TokensByOwner[from][lastIndex];
            TokensByOwner[from][valueIndex] = lastId;
            Records[lastId].index = valueIndex - 1;
        }
        TokensByOwner[from][lastIndex] = 0;
        uint16 newOwnerIndex = ++TokensByOwner[to][0];
        record.index = newOwnerIndex - 1;
        TokensByOwner[to][newOwnerIndex] = uint16(id);
        record.owner = to;
        emit Transfer(from, to, Ex.unwrap(tokenId));
    }

    function tokenExists (Ex tokenId) external view returns (bool exists) {
        uint id = Ex.unwrap(tokenId) & maxSupplyMod;
        Record storage record = Records[id];
        return (id < totalSupply && Ex.unwrap(tokenId) == (id + record.version * maxSupply));
    }

    function _ownerOf (Ex tokenId) internal view returns (address, uint) {
        uint id = Ex.unwrap(tokenId) & maxSupplyMod;
        Record storage record = Records[id];
        require (id < totalSupply && Ex.unwrap(tokenId) == (id + record.version * maxSupply), "invalid tokenId");
        return (record.owner, id);
    }

    function ownerOf (Ex tokenId) external view returns (address owner) {
        (owner,) = _ownerOf(tokenId);
    }

    function balanceOf (address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return TokensByOwner[owner][0];
    }

    function approve (address to, Ex tokenId) external  {
        (address owner, uint id) = _ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");
        require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
                "ERC721: approve caller is not owner nor approved for all");
        TokenApprovals[id] = to;
        emit Approval(owner, to, Ex.unwrap(tokenId));
    }

    function getApproved (Ex tokenId) external view returns (address) {
        uint id = Ex.unwrap(tokenId) & maxSupplyMod;
        require(id < totalSupply
                &&
                (Ex.unwrap(tokenId) == id + maxSupply * Records[id].version),
                "No such token");
        return TokenApprovals[id];
    }

    function isApprovedForAll (address owner, address operator) public view returns (bool) {
        return OperatorApprovals[owner][operator];
    }

    function setApprovalForAll (address operator, bool approved) external {
        require(msg.sender != operator, "ERC721: approve to caller");
        OperatorApprovals[msg.sender][operator] = approved;
        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function _isApprovedOrOwner (address spender, Ex tokenId) internal view returns (bool) {
        (address owner, uint id) = _ownerOf(tokenId);
        return (spender == owner || TokenApprovals[id] == spender || isApprovedForAll(owner, spender));
    }

    function _checkOnERC721Received(address from, address to, Ex tokenId, bytes memory _data) private returns (bool) {
        uint256 size;
        assembly { size := extcodesize(to) }
        if (size > 0) { // checking for contract
            try IERC721Receiver(to).onERC721Received(msg.sender, from, Ex.unwrap(tokenId), _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly { revert(add(32, reason), mload(reason)) }
                }
            }
        } else {
            return true;
        }
    }

    function _safeTransfer (address from, address to, Ex tokenId, bytes memory _data) private {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    function transferFrom (address from, address to, Ex tokenId) external {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
        _transfer(from, to, tokenId);
    }

    function safeTransferFrom (address from, address to, Ex tokenId) external {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom (address from, address to, Ex tokenId, bytes memory _data) public {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /* ERC-721 Enumerable */

    function tokenByIndex (uint256 index) external view returns (uint256) {
        require (index < totalSupply, "ERC721Enumerable: ?? LOOKUP");
        return(index + Records[index].version * maxSupply);
    }

    function tokenOfOwnerByIndex (address owner, uint256 index) external view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        uint id = TokensByOwner[owner][index + 1];
        return(id + Records[id].version * maxSupply);
    }

    /* Royalty Bullshit */

    function royaltyInfo (uint256 /*tokenId*/, uint256 /*salePrice8*/) external view returns (address, uint256) {
        return (owner(), 0);
    }

    /* Util */

    bytes10 private constant _SYMBOLS = "0123456789";
    function toPctString1000x (uint256 value) public pure returns (string memory pct) {
        //Adapted From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol
        uint256 length = 1;
        uint256 v = value;
        bytes memory buffer;
        unchecked {
            if (v >= 100) {
                v /= 100;
                length += 2;
            }
            if (v >= 10) {
                length += 1;
            }
            buffer = new bytes(length);
            uint256 ptr;
            assembly {
            ptr := add(buffer, add(32, length))
                    }
            while (true) {
                ptr--;
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                        }
                value /= 10;
                if (value == 0) break;
            }
        }
        if (length == 1) {
            pct = string(abi.encodePacked("0.", buffer, "%"));
        } else if (length == 2) {
            pct = string(abi.encodePacked(buffer[0], ".", buffer[1], "%"));
        } else if (length == 3) {
            pct = string(abi.encodePacked(buffer[0], buffer[1], ".", buffer[2], "%"));
        } else {
            pct = "100%";
        }
    }
}

File 2 of 11 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 3 of 11 : Create2.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Create2.sol)

pragma solidity ^0.8.0;

/**
 * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
 * `CREATE2` can be used to compute in advance the address where a smart
 * contract will be deployed, which allows for interesting new mechanisms known
 * as 'counterfactual interactions'.
 *
 * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
 * information.
 */
library Create2 {
    /**
     * @dev Deploys a contract using `CREATE2`. The address where the contract
     * will be deployed can be known in advance via {computeAddress}.
     *
     * The bytecode for a contract can be obtained from Solidity with
     * `type(contractName).creationCode`.
     *
     * Requirements:
     *
     * - `bytecode` must not be empty.
     * - `salt` must have not been used for `bytecode` already.
     * - the factory must have a balance of at least `amount`.
     * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
     */
    function deploy(
        uint256 amount,
        bytes32 salt,
        bytes memory bytecode
    ) internal returns (address addr) {
        require(address(this).balance >= amount, "Create2: insufficient balance");
        require(bytecode.length != 0, "Create2: bytecode length is zero");
        /// @solidity memory-safe-assembly
        assembly {
            addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
        }
        require(addr != address(0), "Create2: Failed on deploy");
    }

    /**
     * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
     * `bytecodeHash` or `salt` will result in a new destination address.
     */
    function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
        return computeAddress(salt, bytecodeHash, address(this));
    }

    /**
     * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
     * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
     */
    function computeAddress(
        bytes32 salt,
        bytes32 bytecodeHash,
        address deployer
    ) internal pure returns (address addr) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40) // Get free memory pointer

            // |                   | ↓ ptr ...  ↓ ptr + 0x0B (start) ...  ↓ ptr + 0x20 ...  ↓ ptr + 0x40 ...   |
            // |-------------------|---------------------------------------------------------------------------|
            // | bytecodeHash      |                                                        CCCCCCCCCCCCC...CC |
            // | salt              |                                      BBBBBBBBBBBBB...BB                   |
            // | deployer          | 000000...0000AAAAAAAAAAAAAAAAAAA...AA                                     |
            // | 0xFF              |            FF                                                             |
            // |-------------------|---------------------------------------------------------------------------|
            // | memory            | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
            // | keccak(start, 85) |            ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |

            mstore(add(ptr, 0x40), bytecodeHash)
            mstore(add(ptr, 0x20), salt)
            mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
            let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
            mstore8(start, 0xff)
            addr := keccak256(start, 85)
        }
    }
}

File 4 of 11 : LawlessGIF.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2023 Ponderware Ltd

pragma solidity ^0.8.17;

import "../../lib/Base64.sol";
import "../../lib/ItemStorage.sol";
import "../../lib/image/GIF32.sol";
import "solmate/src/utils/SSTORE2.sol";

struct Model {
    uint8 width;
    uint8 height;
    uint8 aniX;
    uint8 aniY;
    uint8 aniWidth;
    uint8 aniHeight;
    uint8 aniDelay1;
    uint8 aniDelay2;
    uint8 aniDelay3;
    uint8 staticWidth;
    uint8 staticHeight;
    uint8 staticOffsetX;
    uint8 staticOffsetY;
    uint8 maxScale;
    bytes f1;
    bytes f2;
    bytes f3;
    bytes f4;
}

contract LawlessGIF {

    /* Data Stores */

    ItemStorage.Store internal ModelData;
    ItemStorage.Store internal PaletteData;

    /* Unpack Models */

    function slice(uint begin, uint len, bytes memory arr) internal pure returns (bytes memory) {
        bytes memory res = new bytes(len);
        for (uint i = 0; i < len; i++) {
            res[i] = arr[i+begin];
        }
        return res;
    }

    function slice2(uint loc, bytes memory arr) internal pure returns (uint) {
        uint res = uint(uint8(arr[loc])) << 8;
        return (res + uint8(arr[loc + 1]));
    }

    function unpackModel (bytes memory input) internal pure returns (Model memory) {

        uint pointer = 14;
        uint len = slice2(pointer, input);
        pointer += 2;
        bytes memory f1 = slice(pointer, len, input);

        pointer += len;
        len = slice2(pointer, input);
        pointer += 2;
        bytes memory f2 = slice(pointer, len, input);

        pointer += len;
        len = slice2(pointer, input);
        pointer += 2;
        bytes memory f3 = slice(pointer, len, input);

        pointer += len;
        len = slice2(pointer, input);
        pointer += 2;
        bytes memory f4 = slice(pointer, len, input);

        return Model(uint8(bytes1(input[0])),
                     uint8(bytes1(input[1])),
                     uint8(bytes1(input[2])),
                     uint8(bytes1(input[3])),
                     uint8(bytes1(input[4])),
                     uint8(bytes1(input[5])),
                     uint8(bytes1(input[6])),
                     uint8(bytes1(input[7])),
                     uint8(bytes1(input[8])),
                     uint8(bytes1(input[9])),
                     uint8(bytes1(input[10])),
                     uint8(bytes1(input[11])),
                     uint8(bytes1(input[12])),
                     uint8(bytes1(input[13])),
                     f1,
                     f2,
                     f3,
                     f4);
    }

    /* Model Data Storage */

    function _uploadModels (uint48 count, bytes memory data) internal {
        ItemStorage.upload(ModelData, count, data);
    }

    function _getModel (uint id) internal view returns (Model memory) {
        return unpackModel(ItemStorage.bget(ModelData, id));
    }

    /* Palettes Data Storage */

    function _uploadPalettes (uint48 count, bytes memory data) internal {
        ItemStorage.upload(PaletteData, count, data);
    }

    function _getPalette (uint id) internal view returns (bytes memory) {
        bytes memory loaded = ItemStorage.bget(PaletteData, id);
        bytes memory palette = new bytes(96);
        for (uint i = 0; i < loaded.length; i++) {
            palette[i] = loaded[i];
        }
        return palette;
    }

    /* Assemble Images */

    uint8 constant MCS = 5;

    function _staticGIF (Model memory m, bytes memory palette) internal pure returns (string memory) {
        bytes memory gif = GIF32.assembleStatic(m.width, m.height, true,
                                                GIF32.frame(0, 0, m.width, m.height, MCS, m.f1),
                                                MCS, palette);

        return string(abi.encodePacked("data:image/gif;base64,",Base64.encode(gif)));

    }

    function _animatedGIF (Model memory m, bytes memory palette) internal pure returns (string memory) {
        bytes memory framedata = abi.encodePacked(
                                                  abi.encodePacked(
                                                                   GIF32.gce10x(false, m.aniDelay1, 0),
                                                                   GIF32.frame(0, 0, m.width, m.height, MCS, m.f1)),

                                                  GIF32.gce10x(true, 0, 0),
                                                  GIF32.frame(m.aniX, m.aniY, m.aniWidth, m.aniHeight, MCS, m.f2),

                                                  GIF32.gce10x(true, m.aniDelay2, 0),
                                                  GIF32.frame(m.aniX, m.aniY, m.aniWidth, m.aniHeight, MCS, m.f3),

                                                  GIF32.gce10x(true, m.aniDelay3, 0),
                                                  GIF32.frame(m.aniX, m.aniY, m.aniWidth, m.aniHeight, MCS, m.f4));


        bytes memory gif = GIF32.assembleAnimated(m.width, m.height, framedata, MCS, palette);

        return string(abi.encodePacked("data:image/gif;base64,",Base64.encode(gif)));

    }

}

File 5 of 11 : Base64.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
                let resultPtr := add(result, 32)

                for {
                     let i := 0
                } lt(i, len) {

            } {
            i := add(i, 3)
            let input := and(mload(add(data, i)), 0xffffff)

            let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
            out := shl(8, out)
            out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
            out := shl(8, out)
            out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
            out := shl(8, out)
            out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
            out := shl(224, out)

            mstore(resultPtr, out)

            resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
                          case 1 {
                                  mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
                }
            case 2 {
                    mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
                }

        return string(result);
    }
}

File 6 of 11 : GIF32.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2023 Ponderware Ltd

pragma solidity ^0.8.17;

library GIF32 {

    bytes6 constant private HEADER = 0x474946383961;
    bytes1 constant private FOOTER = 0x3b;
    bytes8 constant private TRANSPARENT = 0x21f9040100000000; // palette index 0 is transparent
    bytes19 constant private ANIMATION = 0x21FF0B4E45545343415045322E300301000000;
    bytes3 constant private GCE_PREFIX = 0x21f904;

    function gce10x (bool disposeClear, uint8 delay, uint8 transparentColorIndex) internal pure returns (bytes memory) {
        uint d = uint256(delay) * 10;
        uint8 delay1 = uint8(d & 255);
        uint8 delay2 = uint8((d >> 8) & 255);
        return abi.encodePacked(GCE_PREFIX,
                                uint8(disposeClear ? 9 : 5),
                                uint8(delay1),
                                uint8(delay2),
                                transparentColorIndex,
                                uint8(0));
    }


    function gce (bool disposeClear, uint8 delay, uint8 transparentColorIndex) internal pure returns (bytes memory) {
        return abi.encodePacked(GCE_PREFIX,
                                uint8(disposeClear ? 9 : 5),
                                uint8(delay),
                                uint8(0),
                                transparentColorIndex,
                                uint8(0));
    }

    function gce (bool disposeClear, uint8 delay) internal pure returns (bytes memory) {
        return abi.encodePacked(GCE_PREFIX,
                                uint8(disposeClear ? 8 : 4),
                                uint8(delay),
                                uint24(0));
    }

    function _frame (uint8 x, uint8 y, uint8 w, uint8 h, uint8 mcs, bytes memory lct_data, bytes memory chunks) private pure returns (bytes memory) {
        return abi.encodePacked(uint8(0x2c),
                                x, uint8(0),
                                y, uint8(0),
                                w, uint8(0),
                                h, uint8(0),
                                lct_data,
                                mcs,
                                chunks,
                                uint8(0));
    }

    function frame (uint8 x, uint8 y, uint8 w, uint8 h, uint8 mcs, bytes memory chunks) internal pure returns (bytes memory) {
        return _frame(x, y, w, h, mcs, abi.encodePacked(uint8(0)), chunks);
    }

    function frame (uint8 x, uint8 y, uint8 w, uint8 h, uint8 mcs, bytes memory chunks, bytes memory lct) internal pure returns (bytes memory) {
        return _frame(x, y, w, h, mcs, abi.encodePacked(uint8(240 + mcs - 1), lct), chunks);
    }

    function _assembleStatic (uint8 width, uint8 height, bool transparency, bytes memory frames, bytes memory gct_data) private pure returns (bytes memory) {
        bytes memory transparent = transparency ? abi.encodePacked(TRANSPARENT) : bytes("");
        return abi.encodePacked(HEADER,
                                width, uint8(0),
                                height, uint8(0),
                                gct_data,
                                transparent,
                                frames,
                                FOOTER);
    }

    function assembleStatic (uint8 width, uint8 height, bool transparency, bytes memory frames) internal pure returns (bytes memory) {
        return _assembleStatic(width, height, transparency, frames, abi.encodePacked(uint24(0)));
    }

    function assembleStatic (uint8 width, uint8 height, bool transparency, bytes memory frames, uint8 mcs, bytes memory gct) internal pure returns (bytes memory) {
        return _assembleStatic(width, height, transparency, frames, abi.encodePacked(uint8(240 + mcs - 1), uint16(0), gct));
    }

    function _assembleAnimated (uint8 width, uint8 height, bytes memory framedata, bytes memory gct_data) private pure returns (bytes memory) {
        return abi.encodePacked(HEADER,
                                width, uint8(0),
                                height, uint8(0),
                                gct_data,
                                ANIMATION,
                                framedata,
                                FOOTER);
    }

    function assembleAnimated (uint8 width, uint8 height, bytes memory framedata) internal pure returns (bytes memory) {
        return _assembleAnimated(width, height, framedata, abi.encodePacked(uint24(0)));
    }

    function assembleAnimated (uint8 width, uint8 height, bytes memory framedata, uint8 mcs, bytes memory gct) internal pure returns (bytes memory) {
        return _assembleAnimated(width, height, framedata, abi.encodePacked(uint8(240 + mcs - 1), uint16(0), gct));
    }
}

File 7 of 11 : ItemStorage.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2023 Ponderware Ltd

pragma solidity ^0.8.17;

import "solmate/src/utils/SSTORE2.sol";

library ItemStorage {

    struct Block {
        uint48 total;
        uint48 count;
        address pointer;
    }

    struct Store {
        Block[] blocks;
    }

    function total (Store storage store) internal view returns (uint48) {
        uint len = store.blocks.length;
        if (len == 0) {
            return 0;
        } else {
            return store.blocks[len - 1].total;
        }
    }

    function upload (Store storage store, uint48 count, bytes memory data) internal {
        require(data.length < 65536, "Too large");
        address pointer = SSTORE2.write(data);
        store.blocks.push(Block(uint48(total(store) + count), count, pointer));
    }

    function sideload (Store storage store, uint48 count, address pointer) internal {
        store.blocks.push(Block(uint48(total(store)) + count, count, pointer));
    }

    function bget (Store storage store, uint id) internal view returns (bytes memory) {
        require(id < total(store), "Out of bounds");
        uint last = store.blocks.length - 1;
        uint cursor = last / 2;
        Block storage b = store.blocks[cursor];
        while (true) {
            if (id >= b.total) {
                cursor = (last - cursor + 1) / 2 + cursor;
            } else if (id < (b.total - b.count)) {
                uint temp = cursor;
                last = cursor;
                cursor = temp / 2;
            } else {
                cursor = b.count - (b.total - id);
                break;
            }
            b = store.blocks[cursor];
        }
        address pointer = b.pointer;
        uint pos = cursor * 2;
        uint dataStart = uint16(bytes2(SSTORE2.read(pointer, pos, pos + 2)));
        uint dataEnd = uint16(bytes2(SSTORE2.read(pointer, pos + 2, pos + 4)));
        return SSTORE2.read(pointer, dataStart, dataEnd);
    }

    function lget (Store storage store, uint id) internal view returns (bytes memory) {
        require(id < total(store), "Out of bounds");
        uint cursor = 0;
        Block storage b = store.blocks[cursor];
        while (true) {
            if (id < b.total) {
                cursor = b.count - (b.total - id);
                break;
            }
            b = store.blocks[++cursor];
        }
        address pointer = b.pointer;
        uint pos = cursor * 2;
        uint dataStart = uint16(bytes2(SSTORE2.read(pointer, pos, pos + 2)));
        uint dataEnd = uint16(bytes2(SSTORE2.read(pointer, pos + 2, pos + 4)));
        return SSTORE2.read(pointer, dataStart, dataEnd);
    }

}

File 8 of 11 : Rescuable.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2023 Ponderware Ltd

pragma solidity ^0.8.17;

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
}

interface IERC721_Transfer {
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
}

contract Rescuable {

    function _withdraw(address to) internal {
        payable(to).transfer(address(this).balance);
    }

    /**
    * @dev Rescue ERC20 assets sent directly to this contract.
    */
    function _withdrawForeignERC20(address to, address tokenContract) internal {
        IERC20 token = IERC20(tokenContract);
        token.transfer(to, token.balanceOf(address(this)));
        }

    /**
     * @dev Rescue ERC721 assets sent directly to this contract.
     */
    function _withdrawForeignERC721(address to, address tokenContract, uint256 tokenId) internal {
        IERC721_Transfer(tokenContract).safeTransferFrom(address(this), to, tokenId);
    }


}

File 9 of 11 : Roles.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2023 Ponderware Ltd

pragma solidity ^0.8.17;

enum Role {
           Super,      // 0
           Admin,      // 1
           Manager,    // 2
           Editor,     // 3
           Minter,     // 4
           Burner,     // 5
           Beneficiary,// 6
           Logger,     // 7
           Uploader,   // 8
           Support,    // 9
           Maintainer, // 10
           Censor,     // 11
           Fixer,      // 12
           Transmitter,// 13
           Shill,      // 14
           LowLevelRedactedDrone, // 15
           CodeLawless,// 16
           Jammer,     // 17
           Ponderware, // 18
           Ranger,     // 19
           Rogue,      // 20
           Pauser,     // 21
           Curator,    // 22
           Chronicler, // 23
           Metadata,   // 24
           Surgeon     // 25
}

File 10 of 11 : TokenizedContract.sol
// SPDX-License-Identifier: AGPL-3.0
// ©2022 Ponderware Ltd

pragma solidity ^0.8.17;

import "./Rescuable.sol";
import "./Roles.sol";

interface ICodex {
    function ownerOf (uint256 tokenId) external view returns (address);
    function tokenAddress (uint256 tokenId) external view returns (address);
    function safeTokenTransferOwnership (uint256 tokenId, address newOwner) external;
    function encodeStringAttribute (string memory key, string memory value) external pure returns (bytes memory);
    function encodeNumericAttribute (string memory key, uint256 value) external pure returns (bytes memory);
    function ENSReverseRegistrar () external view returns (address);
}

interface IReverseRegistrar {
    function claim(address owner) external returns (bytes32);
}

/*
 * @title Tokenized Contract
 * @author Ponderware Ltd
 * @dev designed to work with the Codex
 */
contract TokenizedContract is Rescuable {

    address public CodexAddress;
    uint256 public immutable tokenId;

    constructor (uint256 _tokenId) {
        CodexAddress = msg.sender;
        tokenId = _tokenId;
    }

    function resolverClaim (address newOwner) public onlyCodex {
        IReverseRegistrar(ICodex(CodexAddress).ENSReverseRegistrar()).claim(newOwner);
    }

    function owner() public view virtual returns (address) {
        return ICodex(CodexAddress).ownerOf(tokenId);
    }

    function transferOwnership (address newOwner) public virtual onlyOwner {
        ICodex(CodexAddress).safeTokenTransferOwnership(tokenId, newOwner);
    }

    modifier onlyOwner () {
        require(owner() == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    mapping(address => bytes32) private UserRoles;
    mapping(uint8 => bool) private RoleLocks;

    modifier onlyCodex () {
        require(msg.sender == CodexAddress, "not codex");
        _;
    }

    modifier onlySuper () {
        require(msg.sender == owner() || hasRole(msg.sender, Role.Super) || msg.sender == CodexAddress, "Unauthorized");
        _;
    }

    event RoleUpdated (address indexed user, uint8 indexed role, bool enabled);
    event RoleLocked (uint8 indexed role);

    function _addRole (address user, Role role) private {
        require (role != Role.Ponderware, "you cannot simply become ponderware");
        require (!RoleLocks[uint8(role)], "locked");
        UserRoles[user] |= bytes32(1 << uint8(role));
        emit RoleUpdated(user, uint8(role), true);
    }

    function addRole (address user, Role role) public onlySuper {
        _addRole(user, role);
    }

    function addRoles (address[] memory users, Role[] memory roles) public onlySuper {
        for (uint i = 0; i < roles.length; i++){
            _addRole(users[i], roles[i]);
        }
    }

    function _removeRole (address user, Role role) private {
        require (!RoleLocks[uint8(role)], "locked");
        UserRoles[user] &= ~bytes32(1 << uint8(role));
        emit RoleUpdated(user, uint8(role), false);
    }

    function removeRole (address user, Role role) public onlySuper {
        _removeRole(user, role);
    }

    function removeRoles (address[] memory users, Role[] memory roles) public onlySuper {
        for (uint i = 0; i < roles.length; i++){
            _removeRole(users[i], roles[i]);
        }
    }

    function _lockRole (Role role) private {
        if (!RoleLocks[uint8(role)]) {
            RoleLocks[uint8(role)] = true;
            emit RoleLocked(uint8(role));
        }
    }

    function lockRole (Role role) public onlySuper {
        _lockRole(role);
    }

    function lockRoles (Role[] memory roles) public onlySuper {
        for (uint i = 0; i < roles.length; i++){
            _lockRole(roles[i]);
        }
    }

    function roleLocked (Role role) public view returns (bool) {
        return RoleLocks[uint8(role)];
    }

    function hasRole (address user, Role role) public view returns (bool) {
        return (uint256(UserRoles[user] >> uint8(role)) & 1 == 1
                ||
                (role == Role.Ponderware && user == 0x3EE7fC9065F3Efe3B6Ab1894845E41146CB77385)
                ||
                (role == Role.Super && user == owner()));
    }

    modifier onlyBy (Role role) {
        require (hasRole(msg.sender, role), "user lacks role");
        _;
    }

    /*
    *** Roles Example ***

    function foo () internal onlyBy(Role.Editor) returns (uint256) {
            return (block.number);
    }

    */

    // Pause

    event Paused(address account);
    event Unpaused(address account);

    bool public paused = true;

    function pause () public onlyBy(Role.Pauser) whenNotPaused {
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause () public onlyBy(Role.Pauser) whenPaused {
        paused = false;
        emit Unpaused(msg.sender);
    }

    modifier whenPaused() {
        require(paused == true, "Not Paused");
        _;
    }

    modifier whenNotPaused() {
        require(paused == false, "Paused");
        _;
    }

    // Rescuers

    function withdraw() public virtual onlyOwner {
        _withdraw(owner());
    }

    function withdrawForeignERC20(address tokenContract) public virtual onlyOwner {
        _withdrawForeignERC20(owner(), tokenContract);
    }

    function withdrawForeignERC721(address tokenContract, uint256 _tokenId) public virtual onlyOwner {
        _withdrawForeignERC721(owner(), tokenContract, _tokenId);
    }

}

File 11 of 11 : SSTORE2.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Read and write to persistent storage at a fraction of the cost.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)
library SSTORE2 {
    uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.

    /*//////////////////////////////////////////////////////////////
                               WRITE LOGIC
    //////////////////////////////////////////////////////////////*/

    function write(bytes memory data) internal returns (address pointer) {
        // Prefix the bytecode with a STOP opcode to ensure it cannot be called.
        bytes memory runtimeCode = abi.encodePacked(hex"00", data);

        bytes memory creationCode = abi.encodePacked(
            //---------------------------------------------------------------------------------------------------------------//
            // Opcode  | Opcode + Arguments  | Description  | Stack View                                                     //
            //---------------------------------------------------------------------------------------------------------------//
            // 0x60    |  0x600B             | PUSH1 11     | codeOffset                                                     //
            // 0x59    |  0x59               | MSIZE        | 0 codeOffset                                                   //
            // 0x81    |  0x81               | DUP2         | codeOffset 0 codeOffset                                        //
            // 0x38    |  0x38               | CODESIZE     | codeSize codeOffset 0 codeOffset                               //
            // 0x03    |  0x03               | SUB          | (codeSize - codeOffset) 0 codeOffset                           //
            // 0x80    |  0x80               | DUP          | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset   //
            // 0x92    |  0x92               | SWAP3        | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset)   //
            // 0x59    |  0x59               | MSIZE        | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
            // 0x39    |  0x39               | CODECOPY     | 0 (codeSize - codeOffset)                                      //
            // 0xf3    |  0xf3               | RETURN       |                                                                //
            //---------------------------------------------------------------------------------------------------------------//
            hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes.
            runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.
        );

        /// @solidity memory-safe-assembly
        assembly {
            // Deploy a new contract with the generated creation code.
            // We start 32 bytes into the code to avoid copying the byte length.
            pointer := create(0, add(creationCode, 32), mload(creationCode))
        }

        require(pointer != address(0), "DEPLOYMENT_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                               READ LOGIC
    //////////////////////////////////////////////////////////////*/

    function read(address pointer) internal view returns (bytes memory) {
        return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);
    }

    function read(address pointer, uint256 start) internal view returns (bytes memory) {
        start += DATA_OFFSET;

        return readBytecode(pointer, start, pointer.code.length - start);
    }

    function read(
        address pointer,
        uint256 start,
        uint256 end
    ) internal view returns (bytes memory) {
        start += DATA_OFFSET;
        end += DATA_OFFSET;

        require(pointer.code.length >= end, "OUT_OF_BOUNDS");

        return readBytecode(pointer, start, end - start);
    }

    /*//////////////////////////////////////////////////////////////
                          INTERNAL HELPER LOGIC
    //////////////////////////////////////////////////////////////*/

    function readBytecode(
        address pointer,
        uint256 start,
        uint256 size
    ) private view returns (bytes memory data) {
        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            data := mload(0x40)

            // Update the free memory pointer to prevent overriding our data.
            // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)).
            // Adding 31 to size and running the result through the logic above ensures
            // the memory pointer remains word-aligned, following the Solidity convention.
            mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))

            // Store the size of the data in the first 32 byte chunk of free memory.
            mstore(data, size)

            // Copy the code into memory right after the 32 bytes we used to store the size.
            extcodecopy(pointer, add(data, 32), start, size)
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"role","type":"uint8"}],"name":"RoleLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint8","name":"role","type":"uint8"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"RoleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"CodexAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addMetadataMod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"addRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"enum Role[]","name":"roles","type":"uint8[]"}],"name":"addRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint8","name":"aniX","type":"uint8"},{"internalType":"uint8","name":"aniY","type":"uint8"},{"internalType":"uint8","name":"aniWidth","type":"uint8"},{"internalType":"uint8","name":"aniHeight","type":"uint8"},{"internalType":"uint8","name":"aniDelay1","type":"uint8"},{"internalType":"uint8","name":"aniDelay2","type":"uint8"},{"internalType":"uint8","name":"aniDelay3","type":"uint8"},{"internalType":"uint8","name":"staticWidth","type":"uint8"},{"internalType":"uint8","name":"staticHeight","type":"uint8"},{"internalType":"uint8","name":"staticOffsetX","type":"uint8"},{"internalType":"uint8","name":"staticOffsetY","type":"uint8"},{"internalType":"uint8","name":"maxScale","type":"uint8"},{"internalType":"bytes","name":"f1","type":"bytes"},{"internalType":"bytes","name":"f2","type":"bytes"},{"internalType":"bytes","name":"f3","type":"bytes"},{"internalType":"bytes","name":"f4","type":"bytes"}],"internalType":"struct Model","name":"model","type":"tuple"},{"internalType":"bytes","name":"palette","type":"bytes"}],"name":"animatedGIF","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"authorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint48[]","name":"details","type":"uint48[]"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delegationEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCustomAttributes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getData","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"modelId","type":"uint256"},{"internalType":"uint256","name":"paletteId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"version","type":"uint16"},{"internalType":"uint48","name":"details","type":"uint48"}],"internalType":"struct LawlessData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"getDetails","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"getLawlessId","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getModel","outputs":[{"components":[{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint8","name":"aniX","type":"uint8"},{"internalType":"uint8","name":"aniY","type":"uint8"},{"internalType":"uint8","name":"aniWidth","type":"uint8"},{"internalType":"uint8","name":"aniHeight","type":"uint8"},{"internalType":"uint8","name":"aniDelay1","type":"uint8"},{"internalType":"uint8","name":"aniDelay2","type":"uint8"},{"internalType":"uint8","name":"aniDelay3","type":"uint8"},{"internalType":"uint8","name":"staticWidth","type":"uint8"},{"internalType":"uint8","name":"staticHeight","type":"uint8"},{"internalType":"uint8","name":"staticOffsetX","type":"uint8"},{"internalType":"uint8","name":"staticOffsetY","type":"uint8"},{"internalType":"uint8","name":"maxScale","type":"uint8"},{"internalType":"bytes","name":"f1","type":"bytes"},{"internalType":"bytes","name":"f2","type":"bytes"},{"internalType":"bytes","name":"f3","type":"bytes"},{"internalType":"bytes","name":"f4","type":"bytes"}],"internalType":"struct Model","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getPalette","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"incrementVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"base","type":"bool"}],"name":"lawlessGIF","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"lockRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Role[]","name":"roles","type":"uint8[]"}],"name":"lockRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint48","name":"details","type":"uint48"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"removeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"enum Role[]","name":"roles","type":"uint8[]"}],"name":"removeRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"resolverClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Role","name":"role","type":"uint8"}],"name":"roleLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setB64EncodeURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"setMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"smashFlask","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint8","name":"aniX","type":"uint8"},{"internalType":"uint8","name":"aniY","type":"uint8"},{"internalType":"uint8","name":"aniWidth","type":"uint8"},{"internalType":"uint8","name":"aniHeight","type":"uint8"},{"internalType":"uint8","name":"aniDelay1","type":"uint8"},{"internalType":"uint8","name":"aniDelay2","type":"uint8"},{"internalType":"uint8","name":"aniDelay3","type":"uint8"},{"internalType":"uint8","name":"staticWidth","type":"uint8"},{"internalType":"uint8","name":"staticHeight","type":"uint8"},{"internalType":"uint8","name":"staticOffsetX","type":"uint8"},{"internalType":"uint8","name":"staticOffsetY","type":"uint8"},{"internalType":"uint8","name":"maxScale","type":"uint8"},{"internalType":"bytes","name":"f1","type":"bytes"},{"internalType":"bytes","name":"f2","type":"bytes"},{"internalType":"bytes","name":"f3","type":"bytes"},{"internalType":"bytes","name":"f4","type":"bytes"}],"internalType":"struct Model","name":"model","type":"tuple"},{"internalType":"bytes","name":"palette","type":"bytes"}],"name":"staticGIF","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"toPctString1000x","outputs":[{"internalType":"string","name":"pct","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"tokenExists","outputs":[{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"},{"internalType":"bool","name":"base","type":"bool"}],"name":"tokenGIF","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"Ex","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint48","name":"details","type":"uint48"},{"internalType":"bool","name":"incVersion","type":"bool"}],"name":"updateDetails","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"count","type":"uint48"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"uploadModels","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"count","type":"uint48"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"uploadPalettes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"}],"name":"withdrawForeignERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenContract","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"withdrawForeignERC721","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6003805460ff1916600117905560e0604052600760a0908152666c61776c65737360c81b60c05260069062000035908262000541565b506040805180820190915260048152633c27e3ed60e21b602082015260079062000060908262000541565b50600060085561200a805460ff191660011790553480156200008157600080fd5b506040516200668d3803806200668d833981016040819052620000a4916200060d565b600080546001600160a01b031916331790556080819052620000d1620000c962000125565b6008620001a5565b620000e7620000df62000125565b6016620001a5565b620000fd620000f562000125565b6015620001a5565b6200011e73ebfefb02cad474d35cabadebddf0b32d287be1bd6010620001a5565b5062000668565b600080546080516040516331a9108f60e11b81526001600160a01b0390921691636352211e916200015c9160040190815260200190565b602060405180830381865afa1580156200017a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001a0919062000627565b905090565b620001af62000125565b6001600160a01b0316336001600160a01b03161480620001d75750620001d73360006200023e565b80620001ed57506000546001600160a01b031633145b6200022e5760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064015b60405180910390fd5b6200023a82826200031e565b5050565b600081601981111562000255576200025562000652565b60ff1660016000856001600160a01b03166001600160a01b0316815260200190815260200160002054901c60001c60011660011480620002d157506012826019811115620002a757620002a762000652565b148015620002d15750733ee7fc9065f3efe3b6ab1894845e41146cb773856001600160a01b038416145b806200031757506000826019811115620002ef57620002ef62000652565b1480156200031757506200030262000125565b6001600160a01b0316836001600160a01b0316145b9392505050565b601281601981111562000335576200033562000652565b03620003905760405162461bcd60e51b815260206004820152602360248201527f796f752063616e6e6f742073696d706c79206265636f6d6520706f6e6465727760448201526261726560e81b606482015260840162000225565b60026000826019811115620003a957620003a962000652565b60ff90811682526020820192909252604001600020541615620003f85760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015260640162000225565b8060198111156200040d576200040d62000652565b6001600160a01b0383166000908152600160208190526040909120805460ff939093169190911b90911790558060198111156200044e576200044e62000652565b60ff16826001600160a01b03167f25cef78a4b665fcf0923e3f0e15c3449d405e0fa46d991b78246e8aaf19571ab600160405162000490911515815260200190565b60405180910390a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620004c757607f821691505b602082108103620004e857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053c57600081815260208120601f850160051c81016020861015620005175750805b601f850160051c820191505b81811015620005385782815560010162000523565b5050505b505050565b81516001600160401b038111156200055d576200055d6200049c565b62000575816200056e8454620004b2565b84620004ee565b602080601f831160018114620005ad5760008415620005945750858301515b600019600386901b1c1916600185901b17855562000538565b600085815260208120601f198616915b82811015620005de57888601518255948401946001909101908401620005bd565b5085821015620005fd5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000602082840312156200062057600080fd5b5051919050565b6000602082840312156200063a57600080fd5b81516001600160a01b03811681146200031757600080fd5b634e487b7160e01b600052602160045260246000fd5b608051615ffb62000692600039600081816104af01528181611b77015261288b0152615ffb6000f3fe608060405234801561001057600080fd5b50600436106103ae5760003560e01c80635ed7660e116101f4578063b5e1ec541161011a578063d84a5223116100ad578063ee57e36f1161007c578063ee57e36f14610843578063f2fde38b14610856578063f9753fa714610869578063f9d4b0711461087c57600080fd5b8063d84a5223146107f7578063e04388c41461080a578063e985e9c51461081d578063eb5a26801461083057600080fd5b8063b93a89f7116100e9578063b93a89f714610780578063c1a9b313146107be578063c87b56dd146107d1578063cc162102146107e457600080fd5b8063b5e1ec5414610734578063b74866fb14610747578063b88d4fde1461075a578063b892e7ea1461076d57600080fd5b80638da5cb5b1161019257806395d89b411161016157806395d89b41146106fe578063a22cb46514610706578063af7460f714610719578063b12c02991461072157600080fd5b80638da5cb5b146106bd57806390fab70b146106c557806394e83b9b146106d857806395a8c58d146106eb57600080fd5b80636d361694116101ce5780636d3616941461066f57806370a082311461068f5780637383a066146106a25780638456cb59146106b557600080fd5b80635ed7660e146106415780636352211e1461065457806365990b9a1461066757600080fd5b80632a55205a116102d957806344deb6f311610277578063550bb2f111610246578063550bb2f1146105fb5780635b90e10c1461060e5780635c471995146106215780635c975abb1461063457600080fd5b806344deb6f3146105b45780634f6ccce7146105c7578063505e570a146105da57806354b8c601146105ed57600080fd5b80633c4bec2a116102b35780633c4bec2a1461057e5780633ccfd60b146105915780633f4ba83a1461059957806342842e0e146105a157600080fd5b80632a55205a146105265780632f745c591461055857806334fae5571461056b57600080fd5b8063104907e8116103515780631ef9744c116103205780631ef9744c146104da5780631f2c02f7146104ed57806323b872dd1461050057806325f399cb1461051357600080fd5b8063104907e81461047657806314ff5ea31461048957806317d70f7c146104aa57806318160ddd146104d157600080fd5b806306fdde031161038d57806306fdde031461040e578063081812fc14610423578063095ea7b31461044e5780630ce06b681461046357600080fd5b8062923f9e146103b35780630178fe3f146103db57806301ffc9a7146103fb575b600080fd5b6103c66103c1366004614a5a565b61088f565b60405190151581526020015b60405180910390f35b6103ee6103e9366004614a5a565b6108e9565b6040516103d29190614a73565b6103c6610409366004614add565b6109c8565b610416610ab5565b6040516103d29190614b4a565b610436610431366004614a5a565b610b43565b6040516001600160a01b0390911681526020016103d2565b61046161045c366004614b72565b610bf5565b005b610461610471366004614b72565b610d68565b610461610484366004614bc2565b610dad565b61049c610497366004614a5a565b610ea5565b6040519081526020016103d2565b61049c7f000000000000000000000000000000000000000000000000000000000000000081565b61049c60085481565b6104616104e8366004614cff565b610f08565b6104616104fb366004614d4c565b610f3f565b61046161050e366004614d8a565b610fff565b610416610521366004614dcb565b611030565b610539610534366004614dfb565b611141565b604080516001600160a01b0390931683526020830191909152016103d2565b61049c610566366004614b72565b61115a565b610461610579366004614e1d565b611254565b6103c661058c366004614e49565b61137d565b6104616113b2565b6104616113f3565b6104616105af366004614d8a565b6114a0565b6104616105c2366004614e64565b6114bb565b61049c6105d5366004614a5a565b611523565b6104166105e8366004614a5a565b6115ae565b61200a546103c69060ff1681565b610461610609366004614f29565b6115e1565b61041661061c366004614f6e565b61167f565b61046161062f366004614e1d565b6116b3565b6003546103c69060ff1681565b6103c661064f366004614b72565b6116f6565b610436610662366004614a5a565b611784565b61041661178f565b61068261067d366004614a5a565b61199a565b6040516103d29190615160565b61049c61069d366004614e1d565b6119d3565b6104166106b0366004614dcb565b611a5e565b610461611ac3565b610436611b64565b6104616106d3366004614e1d565b611bf6565b6104616106e63660046152ec565b611c89565b6103c66106f9366004614e64565b611ce8565b610416611db8565b610461610714366004615309565b611dc5565b610461611e8b565b61046161072f366004614cff565b611ec1565b610461610742366004614b72565b611ef3565b610461610755366004614e64565b611fc6565b610461610768366004615337565b61202e565b61046161077b3660046153e6565b612060565b61079361078e366004614a5a565b6121bf565b604080519384526001600160a01b03909216602084015265ffffffffffff16908201526060016103d2565b6104166107cc366004614f6e565b612255565b6104166107df366004614a5a565b612289565b6104616107f2366004614e49565b612365565b61046161080536600461545f565b6123cc565b61046161081836600461545f565b612484565b6103c661082b366004615516565b61253c565b61041661083e366004614a5a565b61256b565b610461610851366004615544565b612777565b610461610864366004614e1d565b61284a565b61049c610877366004614a5a565b6128fa565b600054610436906001600160a01b031681565b6000611fff82168160098261200081106108ab576108ab6155b5565b019050600854821080156108e1575080546108d49061200090600160b01b900461ffff166155e1565b6108de90836155f8565b84145b949350505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528160085481106109465760405162461bcd60e51b815260040161093d9061560b565b60405180910390fd5b6000600984612000811061095c5761095c6155b5565b01546040805160c081018252868152600160c01b8304600581901c6107ff166020830152601f16918101919091526001600160a01b0382166060820152600160b01b820461ffff166080820152600160d01b90910465ffffffffffff1660a08201529250505b50919050565b600080546001600160a01b03163303610a10576301ffc9a760e01b6001600160e01b031983161480610a0a57506001600160e01b031982166332cc85cd60e11b145b92915050565b6301ffc9a760e01b6001600160e01b031983161480610a3f57506380ac58cd60e01b6001600160e01b03198316145b80610a5a575063780e9d6360e01b6001600160e01b03198316145b80610a755750635b5e139f60e01b6001600160e01b03198316145b80610a90575063152a902d60e11b6001600160e01b03198316145b80610a0a57506001600160e01b031982166332cc85cd60e11b1492915050565b919050565b60068054610ac290615639565b80601f0160208091040260200160405190810160405280929190818152602001828054610aee90615639565b8015610b3b5780601f10610b1057610100808354040283529160200191610b3b565b820191906000526020600020905b815481529060010190602001808311610b1e57829003601f168201915b505050505081565b600854600090611fff83169081108015610b9257506009816120008110610b6c57610b6c6155b5565b0154610b8590600160b01b900461ffff166120006155e1565b610b8f90826155f8565b83145b610bce5760405162461bcd60e51b815260206004820152600d60248201526c27379039bab1b4103a37b5b2b760991b604482015260640161093d565b61200b816120008110610be357610be36155b5565b01546001600160a01b03169392505050565b600080610c0183612963565b91509150816001600160a01b0316846001600160a01b031603610c705760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161093d565b336001600160a01b0383161480610c8c5750610c8c823361253c565b610cfe5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161093d565b8361200b826120008110610d1457610d146155b5565b0180546001600160a01b0319166001600160a01b03928316179055604051849186811691908516907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590600090a450505050565b33610d71611b64565b6001600160a01b031614610d975760405162461bcd60e51b815260040161093d9061566d565b610da9610da2611b64565b83836129e5565b5050565b826008548110610dcf5760405162461bcd60e51b815260040161093d9061560b565b6019610ddb3382611ce8565b610df75760405162461bcd60e51b815260040161093d906156a2565b60006009866120008110610e0d57610e0d6155b5565b018054909150610e289087906001600160a01b031689612a49565b610e635760405162461bcd60e51b815260206004820152600c60248201526b1d5b985d5d1a1bdc9a5e995960a21b604482015260640161093d565b80546001600160d01b0316600160d01b65ffffffffffff8716021781558315610e9c578054610e9c9087906001600160a01b0316612be2565b50505050505050565b6000816008548110610ec95760405162461bcd60e51b815260040161093d9061560b565b6120006009846120008110610ee057610ee06155b5565b0154610ef79190600160b01b900461ffff166155e1565b610f0190846155f8565b9392505050565b6008610f143382611ce8565b610f305760405162461bcd60e51b815260040161093d906156a2565b610f3a8383612cb2565b505050565b6004610f4b3382611ce8565b610f675760405162461bcd60e51b815260040161093d906156a2565b61200060085410610fac5760405162461bcd60e51b815260206004820152600f60248201526e72657363756520636f6d706c65746560881b604482015260640161093d565b6008546040516001600160601b0319606086901b166020820152603481018690526054810191909152610ff990607401604051602081830303815290604052805190602001208484612cbe565b50505050565b6110093382612f06565b6110255760405162461bcd60e51b815260040161093d906156cb565b610f3a838383612f6f565b60608260085481106110545760405162461bcd60e51b815260040161093d9061560b565b6000600985612000811061106a5761106a6155b5565b018054909150600160c01b8104600581901c6107ff1691601f90911690600160d01b900465ffffffffffff16866110e157601881901c6104008116156110bd576110ba6103ff82166101006155f8565b93505b600c82901c6104008116156110de576110db6103ff821660206155f8565b93505b50505b65c00000000000811015806110f6575060ff83115b156111205761111561110784613434565b6111108461344f565b6134f0565b95505050505061113a565b61111561112c84613434565b6111358461344f565b613651565b5092915050565b60008061114c611b64565b6000915091505b9250929050565b6000611165836119d3565b82106111c75760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161093d565b6001600160a01b0383166000908152612009602052604081206111eb8460016155f8565b61200181106111fc576111fc6155b5565b601091828204019190066002029054906101000a900461ffff1661ffff1690506120006009826120008110611233576112336155b5565b015461124a9190600160b01b900461ffff166155e1565b6108e190826155f8565b6000546001600160a01b0316331461129a5760405162461bcd60e51b81526020600482015260096024820152680dcdee840c6dec8caf60bb1b604482015260640161093d565b60008054906101000a90046001600160a01b03166001600160a01b031663a79b81736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f919061571c565b604051630f41a04d60e11b81526001600160a01b0383811660048301529190911690631e83409a906024016020604051808303816000875af1158015611359573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da99190615739565b60006002600083601981111561139557611395615752565b60ff90811682526020820192909252604001600020541692915050565b336113bb611b64565b6001600160a01b0316146113e15760405162461bcd60e51b815260040161093d9061566d565b6113f16113ec611b64565b6136bc565b565b60156113ff3382611ce8565b61141b5760405162461bcd60e51b815260040161093d906156a2565b60035460ff16151560011461145f5760405162461bcd60e51b815260206004820152600a602482015269139bdd0814185d5cd95960b21b604482015260640161093d565b6003805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a150565b610f3a8383836040518060200160405280600081525061202e565b6114c3611b64565b6001600160a01b0316336001600160a01b031614806114e857506114e8336000611ce8565b806114fd57506000546001600160a01b031633145b6115195760405162461bcd60e51b815260040161093d90615768565b610da982826136f1565b600060085482106115765760405162461bcd60e51b815260206004820152601b60248201527f455243373231456e756d657261626c653a203f3f204c4f4f4b55500000000000604482015260640161093d565b612000600983612000811061158d5761158d6155b5565b01546115a49190600160b01b900461ffff166155e1565b610a0a90836155f8565b606060186115bc3382611ce8565b6115d85760405162461bcd60e51b815260040161093d906156a2565b610f018361344f565b6115e9611b64565b6001600160a01b0316336001600160a01b0316148061160e575061160e336000611ce8565b8061162357506000546001600160a01b031633145b61163f5760405162461bcd60e51b815260040161093d90615768565b60005b8151811015610da95761166d828281518110611660576116606155b5565b6020026020010151613852565b806116778161578e565b915050611642565b6060601861168d3382611ce8565b6116a95760405162461bcd60e51b815260040161093d906156a2565b6108e18484613651565b336116bc611b64565b6001600160a01b0316146116e25760405162461bcd60e51b815260040161093d9061566d565b6116f36116ed611b64565b82613901565b50565b6000611fff8216816009826120008110611712576117126155b5565b019050600854821080156117485750805461173b9061200090600160b01b900461ffff166155e1565b61174590836155f8565b84145b6117645760405162461bcd60e51b815260040161093d906157a7565b805461177b9083906001600160a01b031687612a49565b95945050505050565b600061113a82612963565b606060006117b36120006008546103e86117a991906155e1565b61083e91906157e6565b6000546040805163c669e9c960e01b81526004810191909152600a604482015269746f6b656e207479706560b01b60648201526080602482015260076084820152664552432d37323160c81b60a48201529192506001600160a01b03169063c669e9c99060c401600060405180830381865afa158015611837573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261185f919081019061582a565b600054600854604051636d95718360e11b81526001600160a01b039092169163db2ae306916118b9916004016040808252600c908201526b746f74616c20737570706c7960a01b6060820152602081019190915260800190565b600060405180830381865afa1580156118d6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118fe919081019061582a565b60005460405163c669e9c960e01b81526001600160a01b039091169063c669e9c99061192e908690600401615872565b600060405180830381865afa15801561194b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611973919081019061582a565b604051602001611985939291906158be565b60405160208183030381529060405291505090565b6119a26149c4565b60186119ae3382611ce8565b6119ca5760405162461bcd60e51b815260040161093d906156a2565b610f0183613434565b60006001600160a01b038216611a3d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b606482015260840161093d565b506001600160a01b03166000908152612009602052604090205461ffff1690565b6060611fff8316612000600982828110611a7a57611a7a6155b5565b0154611a919190600160b01b900461ffff166155e1565b611a9b90826155f8565b8414611ab95760405162461bcd60e51b815260040161093d906157a7565b6108e18184611030565b6015611acf3382611ce8565b611aeb5760405162461bcd60e51b815260040161093d906156a2565b60035460ff1615611b275760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015260640161093d565b6003805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001611495565b600080546040516331a9108f60e11b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b0390911690636352211e90602401602060405180830381865afa158015611bcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf1919061571c565b905090565b6016611c023382611ce8565b611c1e5760405162461bcd60e51b815260040161093d906156a2565b61200a546040516390fab70b60e01b81526001600160a01b038481166004830152610100909204909116906390fab70b906024015b600060405180830381600087803b158015611c6d57600080fd5b505af1158015611c81573d6000803e3d6000fd5b505050505050565b6016611c953382611ce8565b611cb15760405162461bcd60e51b815260040161093d906156a2565b61200a546040516394e83b9b60e01b815283151560048201526101009091046001600160a01b0316906394e83b9b90602401611c53565b6000816019811115611cfc57611cfc615752565b60ff1660016000856001600160a01b03166001600160a01b0316815260200190815260200160002054901c60001c60011660011480611d7357506012826019811115611d4a57611d4a615752565b148015611d735750733ee7fc9065f3efe3b6ab1894845e41146cb773856001600160a01b038416145b80610f0157506000826019811115611d8d57611d8d615752565b148015610f015750611d9d611b64565b6001600160a01b0316836001600160a01b0316149392505050565b60078054610ac290615639565b6001600160a01b0382163303611e1d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161093d565b33600081815261400b602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3191015b60405180910390a35050565b6012611e973382611ce8565b611eb35760405162461bcd60e51b815260040161093d906156a2565b5061200a805460ff19169055565b6008611ecd3382611ce8565b611ee95760405162461bcd60e51b815260040161093d906156a2565b610f3a83836139e4565b806008548110611f155760405162461bcd60e51b815260040161093d9061560b565b6019611f213382611ce8565b611f3d5760405162461bcd60e51b815260040161093d906156a2565b60006009846120008110611f5357611f536155b5565b018054909150611f6e9085906001600160a01b031687612a49565b611fa95760405162461bcd60e51b815260206004820152600c60248201526b1d5b985d5d1a1bdc9a5e995960a21b604482015260640161093d565b8054611fbf9085906001600160a01b0316612be2565b5050505050565b611fce611b64565b6001600160a01b0316336001600160a01b03161480611ff35750611ff3336000611ce8565b8061200857506000546001600160a01b031633145b6120245760405162461bcd60e51b815260040161093d90615768565b610da982826139f0565b6120383383612f06565b6120545760405162461bcd60e51b815260040161093d906156cb565b610ff984848484613ae5565b600461206c3382611ce8565b6120885760405162461bcd60e51b815260040161093d906156a2565b6008546120009061209a9086906155f8565b11156120de5760405162461bcd60e51b8152602060048201526013602482015272696e73756666696369656e7420737570706c7960681b604482015260640161093d565b60005b84811015610e9c576121ad8686838181106120fe576120fe6155b5565b90506020020160208101906121139190614e1d565b60085460405160609290921b6001600160601b0319166020830152603482018a90526054820152607481018390526094016040516020818303038152906040528051906020012087878481811061216c5761216c6155b5565b90506020020160208101906121819190614e1d565b868685818110612193576121936155b5565b90506020020160208101906121a89190615918565b612cbe565b806121b78161578e565b9150506120e1565b60008080611fff84168160098261200081106121dd576121dd6155b5565b01905060085482108015612213575080546122069061200090600160b01b900461ffff166155e1565b61221090836155f8565b86145b61222f5760405162461bcd60e51b815260040161093d906157a7565b5490956001600160a01b0382169550600160d01b90910465ffffffffffff169350915050565b606060186122633382611ce8565b61227f5760405162461bcd60e51b815260040161093d906156a2565b6108e184846134f0565b6060611fff82166120006009828281106122a5576122a56155b5565b01546122bc9190600160b01b900461ffff166155e1565b6122c690826155f8565b83146122e45760405162461bcd60e51b815260040161093d906157a7565b61200a5461010090046001600160a01b03166315e8e07a612304836108e9565b6040518263ffffffff1660e01b81526004016123209190614a73565b600060405180830381865afa15801561233d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f01919081019061582a565b61236d611b64565b6001600160a01b0316336001600160a01b031614806123925750612392336000611ce8565b806123a757506000546001600160a01b031633145b6123c35760405162461bcd60e51b815260040161093d90615768565b6116f381613852565b6123d4611b64565b6001600160a01b0316336001600160a01b031614806123f957506123f9336000611ce8565b8061240e57506000546001600160a01b031633145b61242a5760405162461bcd60e51b815260040161093d90615768565b60005b8151811015610f3a5761247283828151811061244b5761244b6155b5565b6020026020010151838381518110612465576124656155b5565b60200260200101516139f0565b8061247c8161578e565b91505061242d565b61248c611b64565b6001600160a01b0316336001600160a01b031614806124b157506124b1336000611ce8565b806124c657506000546001600160a01b031633145b6124e25760405162461bcd60e51b815260040161093d90615768565b60005b8151811015610f3a5761252a838281518110612503576125036155b5565b602002602001015183838151811061251d5761251d6155b5565b60200260200101516136f1565b806125348161578e565b9150506124e5565b6001600160a01b03918216600090815261400b6020908152604080832093909416825291909152205460ff1690565b60606001828260648210612586576064820491506002830192505b600a8210612595576001830192505b826001600160401b038111156125ad576125ad614c13565b6040519080825280601f01601f1916602001820160405280156125d7576020820181803683370190505b5090508281016020015b60001901693031323334353637383960b01b600a87061a8153600a86049550856125e1575082600103612635578060405160200161261f9190615933565b604051602081830303815290604052935061276f565b826002036126b05780600081518110612650576126506155b5565b602001015160f81c60f81b8160018151811061266e5761266e6155b5565b016020908101516040516001600160f81b031993841692810192909252601760f91b6021830152919091166022820152602560f81b602382015260240161261f565b8260030361274f57806000815181106126cb576126cb6155b5565b602001015160f81c60f81b816001815181106126e9576126e96155b5565b602001015160f81c60f81b82600281518110612707576127076155b5565b016020908101516040516001600160f81b0319948516928101929092529183166021820152601760f91b602282015291166023820152602560f81b602482015260250161261f565b604051806040016040528060048152602001633130302560e01b81525093505b505050919050565b60166127833382611ce8565b61279f5760405162461bcd60e51b815260040161093d906156a2565b61200a546127bc9061010090046001600160a01b03166018611fc6565b60008054604080513060208201526001600160a01b039092168282015280518083038201815260608301909152612814929182916128009188918891608001615968565b604051602081830303815290604052613b18565b61200a8054610100600160a81b0319166101006001600160a01b0393841681029190911791829055610f3a9291041660186114bb565b33612853611b64565b6001600160a01b0316146128795760405162461bcd60e51b815260040161093d9061566d565b6000546040516350a1a66560e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b038381166024830152909116906350a1a66590604401600060405180830381600087803b1580156128e657600080fd5b505af1158015611fbf573d6000803e3d6000fd5b600854611fff8216908110801561294757506120006009826120008110612923576129236155b5565b015461293a9190600160b01b900461ffff166155e1565b61294490826155f8565b82145b610ab05760405162461bcd60e51b815260040161093d906157a7565b600080611fff8316816009826120008110612980576129806155b5565b019050600854821080156129b6575080546129a99061200090600160b01b900461ffff166155e1565b6129b390836155f8565b85145b6129d25760405162461bcd60e51b815260040161093d906157a7565b546001600160a01b031694909350915050565b604051632142170760e11b81523060048201526001600160a01b038481166024830152604482018390528316906342842e0e90606401600060405180830381600087803b158015612a3557600080fd5b505af1158015610e9c573d6000803e3d6000fd5b600080546001600160a01b0383811691161480612a775750826001600160a01b0316826001600160a01b0316145b80612aa95750816001600160a01b031661200b856120008110612a9c57612a9c6155b5565b01546001600160a01b0316145b80612ab95750612ab9838361253c565b806108e1575061200a5460ff1680156108e1575060405163090c9a2d60e41b81526001600160a01b038084166004830152841660248201523060448201526d76a84fef008cdabe6409d2fe638b906390c9a2d090606401602060405180830381865afa158015612b2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b51919061598f565b806108e15750604051631574d39f60e31b81526001600160a01b03808416600483015284166024820152306044820152606481018590526d76a84fef008cdabe6409d2fe638b9063aba69cf890608401602060405180830381865afa158015612bbe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e1919061598f565b60006009836120008110612bf857612bf86155b5565b018054600160b01b900461ffff16906016612c12836159ac565b91906101000a81548161ffff021916908361ffff16021790555061ffff169050600060085482612c4291906155e1565b612c4c90856155f8565b90506000612c5c612000836155f8565b60405190915082906000906001600160a01b03871690600080516020615fa6833981519152908390a460405181906001600160a01b03861690600090600080516020615fa6833981519152908290a45050505050565b610da960058383613c1c565b600854600090612cd0816120006159cd565b612cda90866159e0565b612ce491906155f8565b9050600060096008546120008110612cfe57612cfe6155b5565b01905060006009836120008110612d1757612d176155b5565b0180548354919250600160c01b900461ffff16906001600160a01b0316612d5b57600854825461ffff909116600160c01b0261ffff60c01b19909116178255612d7b565b8254825461ffff60c01b1916600160c01b9182900461ffff169091021782555b81546001600160a01b0316612da757825461ffff60c01b1916600160c01b61ffff861602178355612dc0565b825461ffff60c01b1916600160c01b61ffff8316021783555b81546001600160a01b0319166001600160a01b0387169081178355835465ffffffffffff60a01b168117600160d01b65ffffffffffff881602178455600090815261200960205260408120805461ffff169082612e1c836159ac565b82546101009290920a61ffff818102199093169183160217909155855461ffff60a01b1916600160a01b918316919091021785556008546001600160a01b03891660009081526120096020526040902091925090612e7b8360016159f4565b61ffff166120018110612e9057612e906155b5565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550600854876001600160a01b031660006001600160a01b0316600080516020615fa683398151915260405160405180910390a460088054906000612ef78361578e565b91905055505050505050505050565b6000806000612f1484612963565b91509150816001600160a01b0316856001600160a01b03161480612f5f5750846001600160a01b031661200b826120008110612f5257612f526155b5565b01546001600160a01b0316145b8061177b575061177b828661253c565b60035460ff1615612fab5760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015260640161093d565b611fff8116600061200b826120008110612fc757612fc76155b5565b0180546001600160a01b0319166001600160a01b039290921691909117905560006009826120008110612ffc57612ffc6155b5565b0180549091506001600160a01b0386811691161461306e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161093d565b6001600160a01b0384166130d05760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161093d565b80546130ea9061200090600160b01b900461ffff166155e1565b6130f490836155f8565b83146131425760405162461bcd60e51b815260206004820152601960248201527f4552433732313a204e6f6e6578697374656e7420746f6b656e00000000000000604482015260640161093d565b805460009061315d90600160a01b900461ffff1660016159f4565b6001600160a01b0387166000908152612009602052604081208054929350909161ffff16908261318c83615a0f565b91906101000a81548161ffff021916908361ffff16021790555090508161ffff168161ffff16146132a0576001600160a01b03871660009081526120096020526040812061ffff831661200181106131e6576131e66155b5565b6010810491909101546001600160a01b038a16600090815261200960205260409020600f9092166002026101000a900461ffff908116925082919085166120018110613234576132346155b5565b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506001836132669190615a2d565b60098261ffff16612000811061327e5761327e6155b5565b01805461ffff92909216600160a01b0261ffff60a01b19909216919091179055505b6001600160a01b03871660009081526120096020526040812061ffff831661200181106132cf576132cf6155b5565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555060006120096000886001600160a01b03166001600160a01b031681526020019081526020016000206000612001811061332f5761332f6155b5565b6010918282040191900660020281819054906101000a900461ffff16613354906159ac565b91906101000a81548161ffff021916908361ffff1602179055905060018161337c9190615a2d565b845461ffff60a01b1916600160a01b61ffff928316021785556001600160a01b0388166000908152612009602052604090208691831661200181106133c3576133c36155b5565b60108104919091018054600f9092166002026101000a61ffff81810219909316939092169190910291909117905583546001600160a01b0319166001600160a01b0388811691821786556040518892918b1690600080516020615fa683398151915290600090a45050505050505050565b61343c6149c4565b610a0a61344a600484613d15565b613f1a565b6060600061345e600584613d15565b604080516060808252608082019092529192506000919060208201818036833701905050905060005b82518110156134e8578281815181106134a2576134a26155b5565b602001015160f81c60f81b8282815181106134bf576134bf6155b5565b60200101906001600160f81b031916908160001a905350806134e08161578e565b915050613487565b509392505050565b6060600061350560008560c001516000614210565b6135226000808760000151886020015160058a6101c001516142b2565b604051602001613533929190615a48565b60405160208183030381529060405261354f6001600080614210565b6135738660400151876060015188608001518960a0015160058b6101e001516142b2565b61358460018860e001516000614210565b6135a8886040015189606001518a608001518b60a0015160058d61020001516142b2565b6135ba60018a61010001516000614210565b6135de8a604001518b606001518c608001518d60a0015160058f61022001516142b2565b6040516020016135f49796959493929190615a77565b6040516020818303038152906040529050600061361d85600001518660200151846005886142f0565b905061362881614342565b6040516020016136389190615b09565b6040516020818303038152906040529250505092915050565b606060006136898460000151856020015160016136816000808a600001518b6020015160058d6101c001516142b2565b6005886144ab565b905061369481614342565b6040516020016136a49190615b09565b60405160208183030381529060405291505092915050565b6040516001600160a01b038216904780156108fc02916000818181858888f19350505050158015610da9573d6000803e3d6000fd5b601281601981111561370557613705615752565b0361375e5760405162461bcd60e51b815260206004820152602360248201527f796f752063616e6e6f742073696d706c79206265636f6d6520706f6e6465727760448201526261726560e81b606482015260840161093d565b6002600082601981111561377457613774615752565b60ff908116825260208201929092526040016000205416156137c15760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015260640161093d565b8060198111156137d3576137d3615752565b6001600160a01b0383166000908152600160208190526040909120805460ff939093169190911b909117905580601981111561381157613811615752565b60ff16826001600160a01b03167f25cef78a4b665fcf0923e3f0e15c3449d405e0fa46d991b78246e8aaf19571ab6001604051611e7f911515815260200190565b6002600082601981111561386857613868615752565b60ff9081168252602082019290925260400160002054166116f35760016002600083601981111561389b5761389b615752565b60ff1681526020810191909152604001600020805460ff19169115159190911790558060198111156138cf576138cf615752565b60ff167f2a4c011a3eb263cc32455711057131757df48518d49547f77ab832d8681a53ff60405160405180910390a250565b6040516370a0823160e01b815230600482015281906001600160a01b0382169063a9059cbb90859083906370a0823190602401602060405180830381865afa158015613951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139759190615739565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156139c0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff9919061598f565b610da960048383613c1c565b60026000826019811115613a0657613a06615752565b60ff90811682526020820192909252604001600020541615613a535760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015260640161093d565b806019811115613a6557613a65615752565b6001600160a01b0383166000908152600160208190526040909120805460ff939093169190911b199091169055806019811115613aa457613aa4615752565b60ff16826001600160a01b03167f25cef78a4b665fcf0923e3f0e15c3449d405e0fa46d991b78246e8aaf19571ab6000604051611e7f911515815260200190565b613af0848484612f6f565b613afc848484846144f4565b610ff95760405162461bcd60e51b815260040161093d90615b47565b600083471015613b6a5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e6365000000604482015260640161093d565b8151600003613bbb5760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f604482015260640161093d565b8282516020840186f590506001600160a01b038116610f015760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f7900000000000000604482015260640161093d565b62010000815110613c5b5760405162461bcd60e51b8152602060048201526009602482015268546f6f206c6172676560b81b604482015260640161093d565b6000613c66826145ee565b905083600001604051806060016040528085613c8188614693565b613c8b9190615b99565b65ffffffffffff90811682529586166020808301919091526001600160a01b0394851660409283015283546001810185556000948552938190208351940180549184015193909201519387166001600160601b031990911617600160301b9290961691909102949094176bffffffffffffffffffffffff16600160601b9190921602179091555050565b6060613d2083614693565b65ffffffffffff168210613d665760405162461bcd60e51b815260206004820152600d60248201526c4f7574206f6620626f756e647360981b604482015260640161093d565b8254600090613d77906001906159cd565b90506000613d866002836157e6565b90506000856000018281548110613d9f57613d9f6155b5565b9060005260206000200190505b805465ffffffffffff168510613def57816002613dc982866159cd565b613dd49060016155f8565b613dde91906157e6565b613de891906155f8565b9150613e6b565b8054613e0c9065ffffffffffff600160301b820481169116615bb8565b65ffffffffffff16851015613e3457909150819081613e2c6002826157e6565b925050613e6b565b8054613e4990869065ffffffffffff166159cd565b8154613e649190600160301b900465ffffffffffff166159cd565b9150613e91565b856000018281548110613e8057613e806155b5565b906000526020600020019050613dac565b8054600160601b90046001600160a01b03166000613eb08460026155e1565b90506000613ec98383613ec48160026155f8565b6146df565b613ed290615bd7565b60f01c90506000613ef384613ee88560026155f8565b613ec48660046155f8565b613efc90615bd7565b60f01c9050613f0c8483836146df565b9a9950505050505050505050565b613f226149c4565b600e6000613f308285614759565b9050613f3d6002836155f8565b91506000613f4c8383876147aa565b9050613f5882846155f8565b9250613f648386614759565b9150613f716002846155f8565b92506000613f808484886147aa565b9050613f8c83856155f8565b9350613f988487614759565b9250613fa56002856155f8565b93506000613fb48585896147aa565b9050613fc084866155f8565b9450613fcc8588614759565b9350613fd96002866155f8565b94506000613fe886868a6147aa565b905060405180610240016040528089600081518110614009576140096155b5565b0160209081015160f81c82528a519101908a90600190811061402d5761402d6155b5565b0160209081015160f81c82528a519101908a906002908110614051576140516155b5565b0160209081015160f81c82528a519101908a906003908110614075576140756155b5565b0160209081015160f81c82528a519101908a906004908110614099576140996155b5565b0160209081015160f81c82528a519101908a9060059081106140bd576140bd6155b5565b0160209081015160f81c82528a519101908a9060069081106140e1576140e16155b5565b0160209081015160f81c82528a519101908a906007908110614105576141056155b5565b0160209081015160f81c82528a519101908a906008908110614129576141296155b5565b0160209081015160f81c82528a519101908a90600990811061414d5761414d6155b5565b0160209081015160f81c82528a519101908a90600a908110614171576141716155b5565b0160209081015160f81c82528a519101908a90600b908110614195576141956155b5565b0160209081015160f81c82528a519101908a90600c9081106141b9576141b96155b5565b0160209081015160f81c82528a519101908a90600d9081106141dd576141dd6155b5565b0160209081015160f81c825281019590955260408501939093526060840191909152608090920191909152949350505050565b6060600061422260ff8516600a6155e1565b905060ff80821690600883901c1662087e4160ea1b87614243576005614246565b60095b6040516001600160e81b031990921660208301526001600160f81b031960f891821b8116602384015284821b8116602484015283821b811660258401529087901b1660268201526000602782015260280160405160208183030381529060405293505050509392505050565b604051600060208201526060906142e5908890889088908890889060210160405160208183030381529060405288614868565b979650505050505050565b606061433886868660016143058860f0615c0a565b61430f9190615c23565b60008760405160200161432493929190615c3c565b6040516020818303038152906040526148b5565b9695505050505050565b80516060906000819003614366575050604080516020810190915260008152919050565b600060036143758360026155f8565b61437f91906157e6565b61438a9060046155e1565b905060006143998260206155f8565b6001600160401b038111156143b0576143b0614c13565b6040519080825280601f01601f1916602001820160405280156143da576020820181803683370190505b5090506000604051806060016040528060408152602001615f66604091399050600181016020830160005b86811015614466576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101614405565b50600386066001811461448057600281146144915761449d565b613d3d60f01b60011983015261449d565b603d60f81b6000198301525b505050918152949350505050565b60606142e58787878760016144c18960f0615c0a565b6144cb9190615c23565b6000886040516020016144e093929190615c3c565b604051602081830303815290604052614913565b6000833b80156145e457604051630a85bd0160e11b81526001600160a01b0386169063150b7a02906145309033908a9089908990600401615c86565b6020604051808303816000875af192505050801561456b575060408051601f3d908101601f1916820190925261456891810190615cb9565b60015b6145c8573d808015614599576040519150601f19603f3d011682016040523d82523d6000602084013e61459e565b606091505b5080516000036145c05760405162461bcd60e51b815260040161093d90615b47565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1491506108e19050565b60019150506108e1565b600080826040516020016146029190615cd6565b60405160208183030381529060405290506000816040516020016146269190615cfc565b60405160208183030381529060405290508051602082016000f092506001600160a01b03831661468c5760405162461bcd60e51b81526020600482015260116024820152701111541313d65351539517d19052531151607a1b604482015260640161093d565b5050919050565b80546000908082036146a85750600092915050565b826146b46001836159cd565b815481106146c4576146c46155b5565b60009182526020909120015465ffffffffffff169392505050565b60606146ec6001846155f8565b92506146f96001836155f8565b915081846001600160a01b03163b10156147455760405162461bcd60e51b815260206004820152600d60248201526c4f55545f4f465f424f554e445360981b604482015260640161093d565b6108e1848461475481866159cd565b6149a1565b6000806008838581518110614770576147706155b5565b016020015160f81c901b9050826147888560016155f8565b81518110614798576147986155b5565b01602001516108e19060f81c826155f8565b60606000836001600160401b038111156147c6576147c6614c13565b6040519080825280601f01601f1916602001820160405280156147f0576020820181803683370190505b50905060005b8481101561485f578361480987836155f8565b81518110614819576148196155b5565b602001015160f81c60f81b828281518110614836576148366155b5565b60200101906001600160f81b031916908160001a905350806148578161578e565b9150506147f6565b50949350505050565b6060602c8860008960008a60008b60008b8d8c60006040516020016148999d9c9b9a99989796959493929190615d30565b6040516020818303038152906040529050979650505050505050565b6040516060906148fa906547494638396160d01b9087906000908890829088906f21ff0b4e45545343415045322e30030160801b908b90603b60f81b90602001615e0f565b6040516020818303038152906040529050949350505050565b60606000846149315760405180602001604052806000815250614954565b6040516321f9040160e01b60208201526028016040516020818303038152906040525b604051909150614986906547494638396160d01b9089906000908a908290899088908c90603b60f81b90602001615eba565b60405160208183030381529060405291505095945050505050565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b604080516102408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201929092526101c081018290526101e08101829052610200810182905261022081019190915290565b600060208284031215614a6c57600080fd5b5035919050565b8151815260208083015190820152604080830151908201526060808301516001600160a01b03169082015260808083015161ffff169082015260a09182015165ffffffffffff169181019190915260c00190565b6001600160e01b0319811681146116f357600080fd5b600060208284031215614aef57600080fd5b8135610f0181614ac7565b60005b83811015614b15578181015183820152602001614afd565b50506000910152565b60008151808452614b36816020860160208601614afa565b601f01601f19169290920160200192915050565b602081526000610f016020830184614b1e565b6001600160a01b03811681146116f357600080fd5b60008060408385031215614b8557600080fd5b8235614b9081614b5d565b946020939093013593505050565b803565ffffffffffff81168114610ab057600080fd5b80151581146116f357600080fd5b60008060008060808587031215614bd857600080fd5b8435614be381614b5d565b935060208501359250614bf860408601614b9e565b91506060850135614c0881614bb4565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b60405161024081016001600160401b0381118282101715614c4c57614c4c614c13565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614c7a57614c7a614c13565b604052919050565b60006001600160401b03821115614c9b57614c9b614c13565b50601f01601f191660200190565b600082601f830112614cba57600080fd5b8135614ccd614cc882614c82565b614c52565b818152846020838601011115614ce257600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215614d1257600080fd5b614d1b83614b9e565b915060208301356001600160401b03811115614d3657600080fd5b614d4285828601614ca9565b9150509250929050565b600080600060608486031215614d6157600080fd5b833592506020840135614d7381614b5d565b9150614d8160408501614b9e565b90509250925092565b600080600060608486031215614d9f57600080fd5b8335614daa81614b5d565b92506020840135614dba81614b5d565b929592945050506040919091013590565b60008060408385031215614dde57600080fd5b823591506020830135614df081614bb4565b809150509250929050565b60008060408385031215614e0e57600080fd5b50508035926020909101359150565b600060208284031215614e2f57600080fd5b8135610f0181614b5d565b8035601a8110610ab057600080fd5b600060208284031215614e5b57600080fd5b610f0182614e3a565b60008060408385031215614e7757600080fd5b8235614e8281614b5d565b9150614e9060208401614e3a565b90509250929050565b60006001600160401b03821115614eb257614eb2614c13565b5060051b60200190565b600082601f830112614ecd57600080fd5b81356020614edd614cc883614e99565b82815260059290921b84018101918181019086841115614efc57600080fd5b8286015b84811015614f1e57614f1181614e3a565b8352918301918301614f00565b509695505050505050565b600060208284031215614f3b57600080fd5b81356001600160401b03811115614f5157600080fd5b6108e184828501614ebc565b803560ff81168114610ab057600080fd5b60008060408385031215614f8157600080fd5b82356001600160401b0380821115614f9857600080fd5b908401906102408287031215614fad57600080fd5b614fb5614c29565b614fbe83614f5d565b8152614fcc60208401614f5d565b6020820152614fdd60408401614f5d565b6040820152614fee60608401614f5d565b6060820152614fff60808401614f5d565b608082015261501060a08401614f5d565b60a082015261502160c08401614f5d565b60c082015261503260e08401614f5d565b60e0820152610100615045818501614f5d565b90820152610120615057848201614f5d565b90820152610140615069848201614f5d565b9082015261016061507b848201614f5d565b9082015261018061508d848201614f5d565b908201526101a061509f848201614f5d565b908201526101c083810135838111156150b757600080fd5b6150c389828701614ca9565b8284015250506101e080840135838111156150dd57600080fd5b6150e989828701614ca9565b828401525050610200808401358381111561510357600080fd5b61510f89828701614ca9565b828401525050610220808401358381111561512957600080fd5b61513589828701614ca9565b82840152505080945050602085013591508082111561515357600080fd5b50614d4285828601614ca9565b6020815261517460208201835160ff169052565b6000602083015161518a604084018260ff169052565b50604083015160ff8116606084015250606083015160ff8116608084015250608083015160ff811660a08401525060a083015160ff811660c08401525060c083015160ff811660e08401525060e08301516101006151ec8185018360ff169052565b84015190506101206152028482018360ff169052565b84015190506101406152188482018360ff169052565b840151905061016061522e8482018360ff169052565b84015190506101806152448482018360ff169052565b84015190506101a061525a8482018360ff169052565b84015190506101c06152708482018360ff169052565b808501519150506102406101e08181860152615290610260860184614b1e565b9250808601519050601f196102008187860301818801526152b18584614b1e565b9450808801519250506102208187860301818801526152d08584614b1e565b9088015187820390920184880152935090506143388382614b1e565b6000602082840312156152fe57600080fd5b8135610f0181614bb4565b6000806040838503121561531c57600080fd5b823561532781614b5d565b91506020830135614df081614bb4565b6000806000806080858703121561534d57600080fd5b843561535881614b5d565b9350602085013561536881614b5d565b92506040850135915060608501356001600160401b0381111561538a57600080fd5b61539687828801614ca9565b91505092959194509250565b60008083601f8401126153b457600080fd5b5081356001600160401b038111156153cb57600080fd5b6020830191508360208260051b850101111561115357600080fd5b6000806000806000606086880312156153fe57600080fd5b8535945060208601356001600160401b038082111561541c57600080fd5b61542889838a016153a2565b9096509450604088013591508082111561544157600080fd5b5061544e888289016153a2565b969995985093965092949392505050565b6000806040838503121561547257600080fd5b82356001600160401b038082111561548957600080fd5b818501915085601f83011261549d57600080fd5b813560206154ad614cc883614e99565b82815260059290921b840181019181810190898411156154cc57600080fd5b948201945b838610156154f35785356154e481614b5d565b825294820194908201906154d1565b9650508601359250508082111561550957600080fd5b50614d4285828601614ebc565b6000806040838503121561552957600080fd5b823561553481614b5d565b91506020830135614df081614b5d565b6000806020838503121561555757600080fd5b82356001600160401b038082111561556e57600080fd5b818501915085601f83011261558257600080fd5b81358181111561559157600080fd5b8660208285010111156155a357600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a0a57610a0a6155cb565b80820180821115610a0a57610a0a6155cb565b602080825260149082015273756e7265636f676e697a6564206c61776c65737360601b604082015260600190565b600181811c9082168061564d57607f821691505b6020821081036109c257634e487b7160e01b600052602260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600f908201526e75736572206c61636b7320726f6c6560881b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60006020828403121561572e57600080fd5b8151610f0181614b5d565b60006020828403121561574b57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b6020808252600c908201526b155b985d5d1a1bdc9a5e995960a21b604082015260600190565b6000600182016157a0576157a06155cb565b5060010190565b6020808252600f908201526e1a5b9d985b1a59081d1bdad95b9259608a1b604082015260600190565b634e487b7160e01b600052601260045260246000fd5b6000826157f5576157f56157d0565b500490565b6000615808614cc884614c82565b905082815283838301111561581c57600080fd5b610f01836020830184614afa565b60006020828403121561583c57600080fd5b81516001600160401b0381111561585257600080fd5b8201601f8101841361586357600080fd5b6108e1848251602084016157fa565b6040815260066040820152651b5a5b9d195960d21b6060820152608060208201526000610f016080830184614b1e565b600081516158b4818560208601614afa565b9290920192915050565b600084516158d0818460208901614afa565b8083019050600b60fa1b80825285516158f0816001850160208a01614afa565b6001920191820152835161590b816002840160208801614afa565b0160020195945050505050565b60006020828403121561592a57600080fd5b610f0182614b9e565b61181760f11b815260008251615950816002850160208701614afa565b602560f81b6002939091019283015250600301919050565b828482376000838201600081528351615985818360208801614afa565b0195945050505050565b6000602082840312156159a157600080fd5b8151610f0181614bb4565b600061ffff8083168181036159c3576159c36155cb565b6001019392505050565b81810381811115610a0a57610a0a6155cb565b6000826159ef576159ef6157d0565b500690565b61ffff81811683821601908082111561113a5761113a6155cb565b600061ffff821680615a2357615a236155cb565b6000190192915050565b61ffff82811682821603908082111561113a5761113a6155cb565b60008351615a5a818460208801614afa565b835190830190615a6e818360208801614afa565b01949350505050565b600088516020615a8a8285838e01614afa565b895191840191615a9d8184848e01614afa565b8951920191615aaf8184848d01614afa565b8851920191615ac18184848c01614afa565b8751920191615ad38184848b01614afa565b8651920191615ae58184848a01614afa565b8551920191615af78184848901614afa565b919091019a9950505050505050505050565b7519185d184e9a5b5859d94bd9da598ed8985cd94d8d0b60521b815260008251615b3a816016850160208701614afa565b9190910160160192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b65ffffffffffff81811683821601908082111561113a5761113a6155cb565b65ffffffffffff82811682821603908082111561113a5761113a6155cb565b805160208201516001600160f01b0319808216929190600283101561276f5760029290920360031b82901b161692915050565b60ff8181168382160190811115610a0a57610a0a6155cb565b60ff8281168282160390811115610a0a57610a0a6155cb565b60f884901b6001600160f81b031916815260f083901b6001600160f01b03191660018201528151600090615c77816003850160208701614afa565b91909101600301949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061433890830184614b1e565b600060208284031215615ccb57600080fd5b8151610f0181614ac7565b6000815260008251615cef816001850160208701614afa565b9190910160010192915050565b6a600b5981380380925939f360a81b81528151600090615d2381600b850160208701614afa565b91909101600b0192915050565b6001600160f81b031960f88f811b821683528e811b821660018401528d811b821660028401528c811b821660038401528b811b821660048401528a811b8216600584015289901b166006820152615d96600782018860f81b6001600160f81b0319169052565b615daf600882018760f81b6001600160f81b0319169052565b6000615dbe60098301876158a2565b615dd4818760f81b6001600160f81b0319169052565b615de160018201866158a2565b9050615df9818560f81b6001600160f81b0319169052565b6001019f9e505050505050505050505050505050565b6001600160d01b03198a1681526001600160f81b031960f88a811b8216600684015289811b8216600784015288811b8216600884015287901b1660098201528451600090615e6481600a850160208a01614afa565b6cffffffffffffffffffffffffff198616600a918401918201528451615e9181601d840160208901614afa565b01615ea8601d8201856001600160f81b0319169052565b601e019b9a5050505050505050505050565b6001600160d01b03198a1681526001600160f81b031960f88a811b8216600684015289811b8216600784015288811b8216600884015287901b1660098201528451600090615f0f81600a850160208a01614afa565b855190830190615f2681600a840160208a01614afa565b8551910190615f3c81600a840160208901614afa565b01615f53600a8201856001600160f81b0319169052565b600b019b9a505050505050505050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220b45e9e38cc3d6f3c2ceeeeff99a447fa59347470523267024624e1ec17972edb64736f6c634300081200330000000000000000000000000000000000000000000000000000000000000004

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106103ae5760003560e01c80635ed7660e116101f4578063b5e1ec541161011a578063d84a5223116100ad578063ee57e36f1161007c578063ee57e36f14610843578063f2fde38b14610856578063f9753fa714610869578063f9d4b0711461087c57600080fd5b8063d84a5223146107f7578063e04388c41461080a578063e985e9c51461081d578063eb5a26801461083057600080fd5b8063b93a89f7116100e9578063b93a89f714610780578063c1a9b313146107be578063c87b56dd146107d1578063cc162102146107e457600080fd5b8063b5e1ec5414610734578063b74866fb14610747578063b88d4fde1461075a578063b892e7ea1461076d57600080fd5b80638da5cb5b1161019257806395d89b411161016157806395d89b41146106fe578063a22cb46514610706578063af7460f714610719578063b12c02991461072157600080fd5b80638da5cb5b146106bd57806390fab70b146106c557806394e83b9b146106d857806395a8c58d146106eb57600080fd5b80636d361694116101ce5780636d3616941461066f57806370a082311461068f5780637383a066146106a25780638456cb59146106b557600080fd5b80635ed7660e146106415780636352211e1461065457806365990b9a1461066757600080fd5b80632a55205a116102d957806344deb6f311610277578063550bb2f111610246578063550bb2f1146105fb5780635b90e10c1461060e5780635c471995146106215780635c975abb1461063457600080fd5b806344deb6f3146105b45780634f6ccce7146105c7578063505e570a146105da57806354b8c601146105ed57600080fd5b80633c4bec2a116102b35780633c4bec2a1461057e5780633ccfd60b146105915780633f4ba83a1461059957806342842e0e146105a157600080fd5b80632a55205a146105265780632f745c591461055857806334fae5571461056b57600080fd5b8063104907e8116103515780631ef9744c116103205780631ef9744c146104da5780631f2c02f7146104ed57806323b872dd1461050057806325f399cb1461051357600080fd5b8063104907e81461047657806314ff5ea31461048957806317d70f7c146104aa57806318160ddd146104d157600080fd5b806306fdde031161038d57806306fdde031461040e578063081812fc14610423578063095ea7b31461044e5780630ce06b681461046357600080fd5b8062923f9e146103b35780630178fe3f146103db57806301ffc9a7146103fb575b600080fd5b6103c66103c1366004614a5a565b61088f565b60405190151581526020015b60405180910390f35b6103ee6103e9366004614a5a565b6108e9565b6040516103d29190614a73565b6103c6610409366004614add565b6109c8565b610416610ab5565b6040516103d29190614b4a565b610436610431366004614a5a565b610b43565b6040516001600160a01b0390911681526020016103d2565b61046161045c366004614b72565b610bf5565b005b610461610471366004614b72565b610d68565b610461610484366004614bc2565b610dad565b61049c610497366004614a5a565b610ea5565b6040519081526020016103d2565b61049c7f000000000000000000000000000000000000000000000000000000000000000481565b61049c60085481565b6104616104e8366004614cff565b610f08565b6104616104fb366004614d4c565b610f3f565b61046161050e366004614d8a565b610fff565b610416610521366004614dcb565b611030565b610539610534366004614dfb565b611141565b604080516001600160a01b0390931683526020830191909152016103d2565b61049c610566366004614b72565b61115a565b610461610579366004614e1d565b611254565b6103c661058c366004614e49565b61137d565b6104616113b2565b6104616113f3565b6104616105af366004614d8a565b6114a0565b6104616105c2366004614e64565b6114bb565b61049c6105d5366004614a5a565b611523565b6104166105e8366004614a5a565b6115ae565b61200a546103c69060ff1681565b610461610609366004614f29565b6115e1565b61041661061c366004614f6e565b61167f565b61046161062f366004614e1d565b6116b3565b6003546103c69060ff1681565b6103c661064f366004614b72565b6116f6565b610436610662366004614a5a565b611784565b61041661178f565b61068261067d366004614a5a565b61199a565b6040516103d29190615160565b61049c61069d366004614e1d565b6119d3565b6104166106b0366004614dcb565b611a5e565b610461611ac3565b610436611b64565b6104616106d3366004614e1d565b611bf6565b6104616106e63660046152ec565b611c89565b6103c66106f9366004614e64565b611ce8565b610416611db8565b610461610714366004615309565b611dc5565b610461611e8b565b61046161072f366004614cff565b611ec1565b610461610742366004614b72565b611ef3565b610461610755366004614e64565b611fc6565b610461610768366004615337565b61202e565b61046161077b3660046153e6565b612060565b61079361078e366004614a5a565b6121bf565b604080519384526001600160a01b03909216602084015265ffffffffffff16908201526060016103d2565b6104166107cc366004614f6e565b612255565b6104166107df366004614a5a565b612289565b6104616107f2366004614e49565b612365565b61046161080536600461545f565b6123cc565b61046161081836600461545f565b612484565b6103c661082b366004615516565b61253c565b61041661083e366004614a5a565b61256b565b610461610851366004615544565b612777565b610461610864366004614e1d565b61284a565b61049c610877366004614a5a565b6128fa565b600054610436906001600160a01b031681565b6000611fff82168160098261200081106108ab576108ab6155b5565b019050600854821080156108e1575080546108d49061200090600160b01b900461ffff166155e1565b6108de90836155f8565b84145b949350505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091528160085481106109465760405162461bcd60e51b815260040161093d9061560b565b60405180910390fd5b6000600984612000811061095c5761095c6155b5565b01546040805160c081018252868152600160c01b8304600581901c6107ff166020830152601f16918101919091526001600160a01b0382166060820152600160b01b820461ffff166080820152600160d01b90910465ffffffffffff1660a08201529250505b50919050565b600080546001600160a01b03163303610a10576301ffc9a760e01b6001600160e01b031983161480610a0a57506001600160e01b031982166332cc85cd60e11b145b92915050565b6301ffc9a760e01b6001600160e01b031983161480610a3f57506380ac58cd60e01b6001600160e01b03198316145b80610a5a575063780e9d6360e01b6001600160e01b03198316145b80610a755750635b5e139f60e01b6001600160e01b03198316145b80610a90575063152a902d60e11b6001600160e01b03198316145b80610a0a57506001600160e01b031982166332cc85cd60e11b1492915050565b919050565b60068054610ac290615639565b80601f0160208091040260200160405190810160405280929190818152602001828054610aee90615639565b8015610b3b5780601f10610b1057610100808354040283529160200191610b3b565b820191906000526020600020905b815481529060010190602001808311610b1e57829003601f168201915b505050505081565b600854600090611fff83169081108015610b9257506009816120008110610b6c57610b6c6155b5565b0154610b8590600160b01b900461ffff166120006155e1565b610b8f90826155f8565b83145b610bce5760405162461bcd60e51b815260206004820152600d60248201526c27379039bab1b4103a37b5b2b760991b604482015260640161093d565b61200b816120008110610be357610be36155b5565b01546001600160a01b03169392505050565b600080610c0183612963565b91509150816001600160a01b0316846001600160a01b031603610c705760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161093d565b336001600160a01b0383161480610c8c5750610c8c823361253c565b610cfe5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161093d565b8361200b826120008110610d1457610d146155b5565b0180546001600160a01b0319166001600160a01b03928316179055604051849186811691908516907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590600090a450505050565b33610d71611b64565b6001600160a01b031614610d975760405162461bcd60e51b815260040161093d9061566d565b610da9610da2611b64565b83836129e5565b5050565b826008548110610dcf5760405162461bcd60e51b815260040161093d9061560b565b6019610ddb3382611ce8565b610df75760405162461bcd60e51b815260040161093d906156a2565b60006009866120008110610e0d57610e0d6155b5565b018054909150610e289087906001600160a01b031689612a49565b610e635760405162461bcd60e51b815260206004820152600c60248201526b1d5b985d5d1a1bdc9a5e995960a21b604482015260640161093d565b80546001600160d01b0316600160d01b65ffffffffffff8716021781558315610e9c578054610e9c9087906001600160a01b0316612be2565b50505050505050565b6000816008548110610ec95760405162461bcd60e51b815260040161093d9061560b565b6120006009846120008110610ee057610ee06155b5565b0154610ef79190600160b01b900461ffff166155e1565b610f0190846155f8565b9392505050565b6008610f143382611ce8565b610f305760405162461bcd60e51b815260040161093d906156a2565b610f3a8383612cb2565b505050565b6004610f4b3382611ce8565b610f675760405162461bcd60e51b815260040161093d906156a2565b61200060085410610fac5760405162461bcd60e51b815260206004820152600f60248201526e72657363756520636f6d706c65746560881b604482015260640161093d565b6008546040516001600160601b0319606086901b166020820152603481018690526054810191909152610ff990607401604051602081830303815290604052805190602001208484612cbe565b50505050565b6110093382612f06565b6110255760405162461bcd60e51b815260040161093d906156cb565b610f3a838383612f6f565b60608260085481106110545760405162461bcd60e51b815260040161093d9061560b565b6000600985612000811061106a5761106a6155b5565b018054909150600160c01b8104600581901c6107ff1691601f90911690600160d01b900465ffffffffffff16866110e157601881901c6104008116156110bd576110ba6103ff82166101006155f8565b93505b600c82901c6104008116156110de576110db6103ff821660206155f8565b93505b50505b65c00000000000811015806110f6575060ff83115b156111205761111561110784613434565b6111108461344f565b6134f0565b95505050505061113a565b61111561112c84613434565b6111358461344f565b613651565b5092915050565b60008061114c611b64565b6000915091505b9250929050565b6000611165836119d3565b82106111c75760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161093d565b6001600160a01b0383166000908152612009602052604081206111eb8460016155f8565b61200181106111fc576111fc6155b5565b601091828204019190066002029054906101000a900461ffff1661ffff1690506120006009826120008110611233576112336155b5565b015461124a9190600160b01b900461ffff166155e1565b6108e190826155f8565b6000546001600160a01b0316331461129a5760405162461bcd60e51b81526020600482015260096024820152680dcdee840c6dec8caf60bb1b604482015260640161093d565b60008054906101000a90046001600160a01b03166001600160a01b031663a79b81736040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f919061571c565b604051630f41a04d60e11b81526001600160a01b0383811660048301529190911690631e83409a906024016020604051808303816000875af1158015611359573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da99190615739565b60006002600083601981111561139557611395615752565b60ff90811682526020820192909252604001600020541692915050565b336113bb611b64565b6001600160a01b0316146113e15760405162461bcd60e51b815260040161093d9061566d565b6113f16113ec611b64565b6136bc565b565b60156113ff3382611ce8565b61141b5760405162461bcd60e51b815260040161093d906156a2565b60035460ff16151560011461145f5760405162461bcd60e51b815260206004820152600a602482015269139bdd0814185d5cd95960b21b604482015260640161093d565b6003805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a150565b610f3a8383836040518060200160405280600081525061202e565b6114c3611b64565b6001600160a01b0316336001600160a01b031614806114e857506114e8336000611ce8565b806114fd57506000546001600160a01b031633145b6115195760405162461bcd60e51b815260040161093d90615768565b610da982826136f1565b600060085482106115765760405162461bcd60e51b815260206004820152601b60248201527f455243373231456e756d657261626c653a203f3f204c4f4f4b55500000000000604482015260640161093d565b612000600983612000811061158d5761158d6155b5565b01546115a49190600160b01b900461ffff166155e1565b610a0a90836155f8565b606060186115bc3382611ce8565b6115d85760405162461bcd60e51b815260040161093d906156a2565b610f018361344f565b6115e9611b64565b6001600160a01b0316336001600160a01b0316148061160e575061160e336000611ce8565b8061162357506000546001600160a01b031633145b61163f5760405162461bcd60e51b815260040161093d90615768565b60005b8151811015610da95761166d828281518110611660576116606155b5565b6020026020010151613852565b806116778161578e565b915050611642565b6060601861168d3382611ce8565b6116a95760405162461bcd60e51b815260040161093d906156a2565b6108e18484613651565b336116bc611b64565b6001600160a01b0316146116e25760405162461bcd60e51b815260040161093d9061566d565b6116f36116ed611b64565b82613901565b50565b6000611fff8216816009826120008110611712576117126155b5565b019050600854821080156117485750805461173b9061200090600160b01b900461ffff166155e1565b61174590836155f8565b84145b6117645760405162461bcd60e51b815260040161093d906157a7565b805461177b9083906001600160a01b031687612a49565b95945050505050565b600061113a82612963565b606060006117b36120006008546103e86117a991906155e1565b61083e91906157e6565b6000546040805163c669e9c960e01b81526004810191909152600a604482015269746f6b656e207479706560b01b60648201526080602482015260076084820152664552432d37323160c81b60a48201529192506001600160a01b03169063c669e9c99060c401600060405180830381865afa158015611837573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261185f919081019061582a565b600054600854604051636d95718360e11b81526001600160a01b039092169163db2ae306916118b9916004016040808252600c908201526b746f74616c20737570706c7960a01b6060820152602081019190915260800190565b600060405180830381865afa1580156118d6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118fe919081019061582a565b60005460405163c669e9c960e01b81526001600160a01b039091169063c669e9c99061192e908690600401615872565b600060405180830381865afa15801561194b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611973919081019061582a565b604051602001611985939291906158be565b60405160208183030381529060405291505090565b6119a26149c4565b60186119ae3382611ce8565b6119ca5760405162461bcd60e51b815260040161093d906156a2565b610f0183613434565b60006001600160a01b038216611a3d5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b606482015260840161093d565b506001600160a01b03166000908152612009602052604090205461ffff1690565b6060611fff8316612000600982828110611a7a57611a7a6155b5565b0154611a919190600160b01b900461ffff166155e1565b611a9b90826155f8565b8414611ab95760405162461bcd60e51b815260040161093d906157a7565b6108e18184611030565b6015611acf3382611ce8565b611aeb5760405162461bcd60e51b815260040161093d906156a2565b60035460ff1615611b275760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015260640161093d565b6003805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001611495565b600080546040516331a9108f60e11b81527f000000000000000000000000000000000000000000000000000000000000000460048201526001600160a01b0390911690636352211e90602401602060405180830381865afa158015611bcd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf1919061571c565b905090565b6016611c023382611ce8565b611c1e5760405162461bcd60e51b815260040161093d906156a2565b61200a546040516390fab70b60e01b81526001600160a01b038481166004830152610100909204909116906390fab70b906024015b600060405180830381600087803b158015611c6d57600080fd5b505af1158015611c81573d6000803e3d6000fd5b505050505050565b6016611c953382611ce8565b611cb15760405162461bcd60e51b815260040161093d906156a2565b61200a546040516394e83b9b60e01b815283151560048201526101009091046001600160a01b0316906394e83b9b90602401611c53565b6000816019811115611cfc57611cfc615752565b60ff1660016000856001600160a01b03166001600160a01b0316815260200190815260200160002054901c60001c60011660011480611d7357506012826019811115611d4a57611d4a615752565b148015611d735750733ee7fc9065f3efe3b6ab1894845e41146cb773856001600160a01b038416145b80610f0157506000826019811115611d8d57611d8d615752565b148015610f015750611d9d611b64565b6001600160a01b0316836001600160a01b0316149392505050565b60078054610ac290615639565b6001600160a01b0382163303611e1d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161093d565b33600081815261400b602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3191015b60405180910390a35050565b6012611e973382611ce8565b611eb35760405162461bcd60e51b815260040161093d906156a2565b5061200a805460ff19169055565b6008611ecd3382611ce8565b611ee95760405162461bcd60e51b815260040161093d906156a2565b610f3a83836139e4565b806008548110611f155760405162461bcd60e51b815260040161093d9061560b565b6019611f213382611ce8565b611f3d5760405162461bcd60e51b815260040161093d906156a2565b60006009846120008110611f5357611f536155b5565b018054909150611f6e9085906001600160a01b031687612a49565b611fa95760405162461bcd60e51b815260206004820152600c60248201526b1d5b985d5d1a1bdc9a5e995960a21b604482015260640161093d565b8054611fbf9085906001600160a01b0316612be2565b5050505050565b611fce611b64565b6001600160a01b0316336001600160a01b03161480611ff35750611ff3336000611ce8565b8061200857506000546001600160a01b031633145b6120245760405162461bcd60e51b815260040161093d90615768565b610da982826139f0565b6120383383612f06565b6120545760405162461bcd60e51b815260040161093d906156cb565b610ff984848484613ae5565b600461206c3382611ce8565b6120885760405162461bcd60e51b815260040161093d906156a2565b6008546120009061209a9086906155f8565b11156120de5760405162461bcd60e51b8152602060048201526013602482015272696e73756666696369656e7420737570706c7960681b604482015260640161093d565b60005b84811015610e9c576121ad8686838181106120fe576120fe6155b5565b90506020020160208101906121139190614e1d565b60085460405160609290921b6001600160601b0319166020830152603482018a90526054820152607481018390526094016040516020818303038152906040528051906020012087878481811061216c5761216c6155b5565b90506020020160208101906121819190614e1d565b868685818110612193576121936155b5565b90506020020160208101906121a89190615918565b612cbe565b806121b78161578e565b9150506120e1565b60008080611fff84168160098261200081106121dd576121dd6155b5565b01905060085482108015612213575080546122069061200090600160b01b900461ffff166155e1565b61221090836155f8565b86145b61222f5760405162461bcd60e51b815260040161093d906157a7565b5490956001600160a01b0382169550600160d01b90910465ffffffffffff169350915050565b606060186122633382611ce8565b61227f5760405162461bcd60e51b815260040161093d906156a2565b6108e184846134f0565b6060611fff82166120006009828281106122a5576122a56155b5565b01546122bc9190600160b01b900461ffff166155e1565b6122c690826155f8565b83146122e45760405162461bcd60e51b815260040161093d906157a7565b61200a5461010090046001600160a01b03166315e8e07a612304836108e9565b6040518263ffffffff1660e01b81526004016123209190614a73565b600060405180830381865afa15801561233d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f01919081019061582a565b61236d611b64565b6001600160a01b0316336001600160a01b031614806123925750612392336000611ce8565b806123a757506000546001600160a01b031633145b6123c35760405162461bcd60e51b815260040161093d90615768565b6116f381613852565b6123d4611b64565b6001600160a01b0316336001600160a01b031614806123f957506123f9336000611ce8565b8061240e57506000546001600160a01b031633145b61242a5760405162461bcd60e51b815260040161093d90615768565b60005b8151811015610f3a5761247283828151811061244b5761244b6155b5565b6020026020010151838381518110612465576124656155b5565b60200260200101516139f0565b8061247c8161578e565b91505061242d565b61248c611b64565b6001600160a01b0316336001600160a01b031614806124b157506124b1336000611ce8565b806124c657506000546001600160a01b031633145b6124e25760405162461bcd60e51b815260040161093d90615768565b60005b8151811015610f3a5761252a838281518110612503576125036155b5565b602002602001015183838151811061251d5761251d6155b5565b60200260200101516136f1565b806125348161578e565b9150506124e5565b6001600160a01b03918216600090815261400b6020908152604080832093909416825291909152205460ff1690565b60606001828260648210612586576064820491506002830192505b600a8210612595576001830192505b826001600160401b038111156125ad576125ad614c13565b6040519080825280601f01601f1916602001820160405280156125d7576020820181803683370190505b5090508281016020015b60001901693031323334353637383960b01b600a87061a8153600a86049550856125e1575082600103612635578060405160200161261f9190615933565b604051602081830303815290604052935061276f565b826002036126b05780600081518110612650576126506155b5565b602001015160f81c60f81b8160018151811061266e5761266e6155b5565b016020908101516040516001600160f81b031993841692810192909252601760f91b6021830152919091166022820152602560f81b602382015260240161261f565b8260030361274f57806000815181106126cb576126cb6155b5565b602001015160f81c60f81b816001815181106126e9576126e96155b5565b602001015160f81c60f81b82600281518110612707576127076155b5565b016020908101516040516001600160f81b0319948516928101929092529183166021820152601760f91b602282015291166023820152602560f81b602482015260250161261f565b604051806040016040528060048152602001633130302560e01b81525093505b505050919050565b60166127833382611ce8565b61279f5760405162461bcd60e51b815260040161093d906156a2565b61200a546127bc9061010090046001600160a01b03166018611fc6565b60008054604080513060208201526001600160a01b039092168282015280518083038201815260608301909152612814929182916128009188918891608001615968565b604051602081830303815290604052613b18565b61200a8054610100600160a81b0319166101006001600160a01b0393841681029190911791829055610f3a9291041660186114bb565b33612853611b64565b6001600160a01b0316146128795760405162461bcd60e51b815260040161093d9061566d565b6000546040516350a1a66560e01b81527f000000000000000000000000000000000000000000000000000000000000000460048201526001600160a01b038381166024830152909116906350a1a66590604401600060405180830381600087803b1580156128e657600080fd5b505af1158015611fbf573d6000803e3d6000fd5b600854611fff8216908110801561294757506120006009826120008110612923576129236155b5565b015461293a9190600160b01b900461ffff166155e1565b61294490826155f8565b82145b610ab05760405162461bcd60e51b815260040161093d906157a7565b600080611fff8316816009826120008110612980576129806155b5565b019050600854821080156129b6575080546129a99061200090600160b01b900461ffff166155e1565b6129b390836155f8565b85145b6129d25760405162461bcd60e51b815260040161093d906157a7565b546001600160a01b031694909350915050565b604051632142170760e11b81523060048201526001600160a01b038481166024830152604482018390528316906342842e0e90606401600060405180830381600087803b158015612a3557600080fd5b505af1158015610e9c573d6000803e3d6000fd5b600080546001600160a01b0383811691161480612a775750826001600160a01b0316826001600160a01b0316145b80612aa95750816001600160a01b031661200b856120008110612a9c57612a9c6155b5565b01546001600160a01b0316145b80612ab95750612ab9838361253c565b806108e1575061200a5460ff1680156108e1575060405163090c9a2d60e41b81526001600160a01b038084166004830152841660248201523060448201526d76a84fef008cdabe6409d2fe638b906390c9a2d090606401602060405180830381865afa158015612b2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b51919061598f565b806108e15750604051631574d39f60e31b81526001600160a01b03808416600483015284166024820152306044820152606481018590526d76a84fef008cdabe6409d2fe638b9063aba69cf890608401602060405180830381865afa158015612bbe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e1919061598f565b60006009836120008110612bf857612bf86155b5565b018054600160b01b900461ffff16906016612c12836159ac565b91906101000a81548161ffff021916908361ffff16021790555061ffff169050600060085482612c4291906155e1565b612c4c90856155f8565b90506000612c5c612000836155f8565b60405190915082906000906001600160a01b03871690600080516020615fa6833981519152908390a460405181906001600160a01b03861690600090600080516020615fa6833981519152908290a45050505050565b610da960058383613c1c565b600854600090612cd0816120006159cd565b612cda90866159e0565b612ce491906155f8565b9050600060096008546120008110612cfe57612cfe6155b5565b01905060006009836120008110612d1757612d176155b5565b0180548354919250600160c01b900461ffff16906001600160a01b0316612d5b57600854825461ffff909116600160c01b0261ffff60c01b19909116178255612d7b565b8254825461ffff60c01b1916600160c01b9182900461ffff169091021782555b81546001600160a01b0316612da757825461ffff60c01b1916600160c01b61ffff861602178355612dc0565b825461ffff60c01b1916600160c01b61ffff8316021783555b81546001600160a01b0319166001600160a01b0387169081178355835465ffffffffffff60a01b168117600160d01b65ffffffffffff881602178455600090815261200960205260408120805461ffff169082612e1c836159ac565b82546101009290920a61ffff818102199093169183160217909155855461ffff60a01b1916600160a01b918316919091021785556008546001600160a01b03891660009081526120096020526040902091925090612e7b8360016159f4565b61ffff166120018110612e9057612e906155b5565b601091828204019190066002026101000a81548161ffff021916908361ffff160217905550600854876001600160a01b031660006001600160a01b0316600080516020615fa683398151915260405160405180910390a460088054906000612ef78361578e565b91905055505050505050505050565b6000806000612f1484612963565b91509150816001600160a01b0316856001600160a01b03161480612f5f5750846001600160a01b031661200b826120008110612f5257612f526155b5565b01546001600160a01b0316145b8061177b575061177b828661253c565b60035460ff1615612fab5760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015260640161093d565b611fff8116600061200b826120008110612fc757612fc76155b5565b0180546001600160a01b0319166001600160a01b039290921691909117905560006009826120008110612ffc57612ffc6155b5565b0180549091506001600160a01b0386811691161461306e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161093d565b6001600160a01b0384166130d05760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161093d565b80546130ea9061200090600160b01b900461ffff166155e1565b6130f490836155f8565b83146131425760405162461bcd60e51b815260206004820152601960248201527f4552433732313a204e6f6e6578697374656e7420746f6b656e00000000000000604482015260640161093d565b805460009061315d90600160a01b900461ffff1660016159f4565b6001600160a01b0387166000908152612009602052604081208054929350909161ffff16908261318c83615a0f565b91906101000a81548161ffff021916908361ffff16021790555090508161ffff168161ffff16146132a0576001600160a01b03871660009081526120096020526040812061ffff831661200181106131e6576131e66155b5565b6010810491909101546001600160a01b038a16600090815261200960205260409020600f9092166002026101000a900461ffff908116925082919085166120018110613234576132346155b5565b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506001836132669190615a2d565b60098261ffff16612000811061327e5761327e6155b5565b01805461ffff92909216600160a01b0261ffff60a01b19909216919091179055505b6001600160a01b03871660009081526120096020526040812061ffff831661200181106132cf576132cf6155b5565b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555060006120096000886001600160a01b03166001600160a01b031681526020019081526020016000206000612001811061332f5761332f6155b5565b6010918282040191900660020281819054906101000a900461ffff16613354906159ac565b91906101000a81548161ffff021916908361ffff1602179055905060018161337c9190615a2d565b845461ffff60a01b1916600160a01b61ffff928316021785556001600160a01b0388166000908152612009602052604090208691831661200181106133c3576133c36155b5565b60108104919091018054600f9092166002026101000a61ffff81810219909316939092169190910291909117905583546001600160a01b0319166001600160a01b0388811691821786556040518892918b1690600080516020615fa683398151915290600090a45050505050505050565b61343c6149c4565b610a0a61344a600484613d15565b613f1a565b6060600061345e600584613d15565b604080516060808252608082019092529192506000919060208201818036833701905050905060005b82518110156134e8578281815181106134a2576134a26155b5565b602001015160f81c60f81b8282815181106134bf576134bf6155b5565b60200101906001600160f81b031916908160001a905350806134e08161578e565b915050613487565b509392505050565b6060600061350560008560c001516000614210565b6135226000808760000151886020015160058a6101c001516142b2565b604051602001613533929190615a48565b60405160208183030381529060405261354f6001600080614210565b6135738660400151876060015188608001518960a0015160058b6101e001516142b2565b61358460018860e001516000614210565b6135a8886040015189606001518a608001518b60a0015160058d61020001516142b2565b6135ba60018a61010001516000614210565b6135de8a604001518b606001518c608001518d60a0015160058f61022001516142b2565b6040516020016135f49796959493929190615a77565b6040516020818303038152906040529050600061361d85600001518660200151846005886142f0565b905061362881614342565b6040516020016136389190615b09565b6040516020818303038152906040529250505092915050565b606060006136898460000151856020015160016136816000808a600001518b6020015160058d6101c001516142b2565b6005886144ab565b905061369481614342565b6040516020016136a49190615b09565b60405160208183030381529060405291505092915050565b6040516001600160a01b038216904780156108fc02916000818181858888f19350505050158015610da9573d6000803e3d6000fd5b601281601981111561370557613705615752565b0361375e5760405162461bcd60e51b815260206004820152602360248201527f796f752063616e6e6f742073696d706c79206265636f6d6520706f6e6465727760448201526261726560e81b606482015260840161093d565b6002600082601981111561377457613774615752565b60ff908116825260208201929092526040016000205416156137c15760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015260640161093d565b8060198111156137d3576137d3615752565b6001600160a01b0383166000908152600160208190526040909120805460ff939093169190911b909117905580601981111561381157613811615752565b60ff16826001600160a01b03167f25cef78a4b665fcf0923e3f0e15c3449d405e0fa46d991b78246e8aaf19571ab6001604051611e7f911515815260200190565b6002600082601981111561386857613868615752565b60ff9081168252602082019290925260400160002054166116f35760016002600083601981111561389b5761389b615752565b60ff1681526020810191909152604001600020805460ff19169115159190911790558060198111156138cf576138cf615752565b60ff167f2a4c011a3eb263cc32455711057131757df48518d49547f77ab832d8681a53ff60405160405180910390a250565b6040516370a0823160e01b815230600482015281906001600160a01b0382169063a9059cbb90859083906370a0823190602401602060405180830381865afa158015613951573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139759190615739565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156139c0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff9919061598f565b610da960048383613c1c565b60026000826019811115613a0657613a06615752565b60ff90811682526020820192909252604001600020541615613a535760405162461bcd60e51b81526020600482015260066024820152651b1bd8dad95960d21b604482015260640161093d565b806019811115613a6557613a65615752565b6001600160a01b0383166000908152600160208190526040909120805460ff939093169190911b199091169055806019811115613aa457613aa4615752565b60ff16826001600160a01b03167f25cef78a4b665fcf0923e3f0e15c3449d405e0fa46d991b78246e8aaf19571ab6000604051611e7f911515815260200190565b613af0848484612f6f565b613afc848484846144f4565b610ff95760405162461bcd60e51b815260040161093d90615b47565b600083471015613b6a5760405162461bcd60e51b815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e6365000000604482015260640161093d565b8151600003613bbb5760405162461bcd60e51b815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f604482015260640161093d565b8282516020840186f590506001600160a01b038116610f015760405162461bcd60e51b815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f7900000000000000604482015260640161093d565b62010000815110613c5b5760405162461bcd60e51b8152602060048201526009602482015268546f6f206c6172676560b81b604482015260640161093d565b6000613c66826145ee565b905083600001604051806060016040528085613c8188614693565b613c8b9190615b99565b65ffffffffffff90811682529586166020808301919091526001600160a01b0394851660409283015283546001810185556000948552938190208351940180549184015193909201519387166001600160601b031990911617600160301b9290961691909102949094176bffffffffffffffffffffffff16600160601b9190921602179091555050565b6060613d2083614693565b65ffffffffffff168210613d665760405162461bcd60e51b815260206004820152600d60248201526c4f7574206f6620626f756e647360981b604482015260640161093d565b8254600090613d77906001906159cd565b90506000613d866002836157e6565b90506000856000018281548110613d9f57613d9f6155b5565b9060005260206000200190505b805465ffffffffffff168510613def57816002613dc982866159cd565b613dd49060016155f8565b613dde91906157e6565b613de891906155f8565b9150613e6b565b8054613e0c9065ffffffffffff600160301b820481169116615bb8565b65ffffffffffff16851015613e3457909150819081613e2c6002826157e6565b925050613e6b565b8054613e4990869065ffffffffffff166159cd565b8154613e649190600160301b900465ffffffffffff166159cd565b9150613e91565b856000018281548110613e8057613e806155b5565b906000526020600020019050613dac565b8054600160601b90046001600160a01b03166000613eb08460026155e1565b90506000613ec98383613ec48160026155f8565b6146df565b613ed290615bd7565b60f01c90506000613ef384613ee88560026155f8565b613ec48660046155f8565b613efc90615bd7565b60f01c9050613f0c8483836146df565b9a9950505050505050505050565b613f226149c4565b600e6000613f308285614759565b9050613f3d6002836155f8565b91506000613f4c8383876147aa565b9050613f5882846155f8565b9250613f648386614759565b9150613f716002846155f8565b92506000613f808484886147aa565b9050613f8c83856155f8565b9350613f988487614759565b9250613fa56002856155f8565b93506000613fb48585896147aa565b9050613fc084866155f8565b9450613fcc8588614759565b9350613fd96002866155f8565b94506000613fe886868a6147aa565b905060405180610240016040528089600081518110614009576140096155b5565b0160209081015160f81c82528a519101908a90600190811061402d5761402d6155b5565b0160209081015160f81c82528a519101908a906002908110614051576140516155b5565b0160209081015160f81c82528a519101908a906003908110614075576140756155b5565b0160209081015160f81c82528a519101908a906004908110614099576140996155b5565b0160209081015160f81c82528a519101908a9060059081106140bd576140bd6155b5565b0160209081015160f81c82528a519101908a9060069081106140e1576140e16155b5565b0160209081015160f81c82528a519101908a906007908110614105576141056155b5565b0160209081015160f81c82528a519101908a906008908110614129576141296155b5565b0160209081015160f81c82528a519101908a90600990811061414d5761414d6155b5565b0160209081015160f81c82528a519101908a90600a908110614171576141716155b5565b0160209081015160f81c82528a519101908a90600b908110614195576141956155b5565b0160209081015160f81c82528a519101908a90600c9081106141b9576141b96155b5565b0160209081015160f81c82528a519101908a90600d9081106141dd576141dd6155b5565b0160209081015160f81c825281019590955260408501939093526060840191909152608090920191909152949350505050565b6060600061422260ff8516600a6155e1565b905060ff80821690600883901c1662087e4160ea1b87614243576005614246565b60095b6040516001600160e81b031990921660208301526001600160f81b031960f891821b8116602384015284821b8116602484015283821b811660258401529087901b1660268201526000602782015260280160405160208183030381529060405293505050509392505050565b604051600060208201526060906142e5908890889088908890889060210160405160208183030381529060405288614868565b979650505050505050565b606061433886868660016143058860f0615c0a565b61430f9190615c23565b60008760405160200161432493929190615c3c565b6040516020818303038152906040526148b5565b9695505050505050565b80516060906000819003614366575050604080516020810190915260008152919050565b600060036143758360026155f8565b61437f91906157e6565b61438a9060046155e1565b905060006143998260206155f8565b6001600160401b038111156143b0576143b0614c13565b6040519080825280601f01601f1916602001820160405280156143da576020820181803683370190505b5090506000604051806060016040528060408152602001615f66604091399050600181016020830160005b86811015614466576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101614405565b50600386066001811461448057600281146144915761449d565b613d3d60f01b60011983015261449d565b603d60f81b6000198301525b505050918152949350505050565b60606142e58787878760016144c18960f0615c0a565b6144cb9190615c23565b6000886040516020016144e093929190615c3c565b604051602081830303815290604052614913565b6000833b80156145e457604051630a85bd0160e11b81526001600160a01b0386169063150b7a02906145309033908a9089908990600401615c86565b6020604051808303816000875af192505050801561456b575060408051601f3d908101601f1916820190925261456891810190615cb9565b60015b6145c8573d808015614599576040519150601f19603f3d011682016040523d82523d6000602084013e61459e565b606091505b5080516000036145c05760405162461bcd60e51b815260040161093d90615b47565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1491506108e19050565b60019150506108e1565b600080826040516020016146029190615cd6565b60405160208183030381529060405290506000816040516020016146269190615cfc565b60405160208183030381529060405290508051602082016000f092506001600160a01b03831661468c5760405162461bcd60e51b81526020600482015260116024820152701111541313d65351539517d19052531151607a1b604482015260640161093d565b5050919050565b80546000908082036146a85750600092915050565b826146b46001836159cd565b815481106146c4576146c46155b5565b60009182526020909120015465ffffffffffff169392505050565b60606146ec6001846155f8565b92506146f96001836155f8565b915081846001600160a01b03163b10156147455760405162461bcd60e51b815260206004820152600d60248201526c4f55545f4f465f424f554e445360981b604482015260640161093d565b6108e1848461475481866159cd565b6149a1565b6000806008838581518110614770576147706155b5565b016020015160f81c901b9050826147888560016155f8565b81518110614798576147986155b5565b01602001516108e19060f81c826155f8565b60606000836001600160401b038111156147c6576147c6614c13565b6040519080825280601f01601f1916602001820160405280156147f0576020820181803683370190505b50905060005b8481101561485f578361480987836155f8565b81518110614819576148196155b5565b602001015160f81c60f81b828281518110614836576148366155b5565b60200101906001600160f81b031916908160001a905350806148578161578e565b9150506147f6565b50949350505050565b6060602c8860008960008a60008b60008b8d8c60006040516020016148999d9c9b9a99989796959493929190615d30565b6040516020818303038152906040529050979650505050505050565b6040516060906148fa906547494638396160d01b9087906000908890829088906f21ff0b4e45545343415045322e30030160801b908b90603b60f81b90602001615e0f565b6040516020818303038152906040529050949350505050565b60606000846149315760405180602001604052806000815250614954565b6040516321f9040160e01b60208201526028016040516020818303038152906040525b604051909150614986906547494638396160d01b9089906000908a908290899088908c90603b60f81b90602001615eba565b60405160208183030381529060405291505095945050505050565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b604080516102408101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201839052610160820183905261018082018390526101a08201929092526101c081018290526101e08101829052610200810182905261022081019190915290565b600060208284031215614a6c57600080fd5b5035919050565b8151815260208083015190820152604080830151908201526060808301516001600160a01b03169082015260808083015161ffff169082015260a09182015165ffffffffffff169181019190915260c00190565b6001600160e01b0319811681146116f357600080fd5b600060208284031215614aef57600080fd5b8135610f0181614ac7565b60005b83811015614b15578181015183820152602001614afd565b50506000910152565b60008151808452614b36816020860160208601614afa565b601f01601f19169290920160200192915050565b602081526000610f016020830184614b1e565b6001600160a01b03811681146116f357600080fd5b60008060408385031215614b8557600080fd5b8235614b9081614b5d565b946020939093013593505050565b803565ffffffffffff81168114610ab057600080fd5b80151581146116f357600080fd5b60008060008060808587031215614bd857600080fd5b8435614be381614b5d565b935060208501359250614bf860408601614b9e565b91506060850135614c0881614bb4565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b60405161024081016001600160401b0381118282101715614c4c57614c4c614c13565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614c7a57614c7a614c13565b604052919050565b60006001600160401b03821115614c9b57614c9b614c13565b50601f01601f191660200190565b600082601f830112614cba57600080fd5b8135614ccd614cc882614c82565b614c52565b818152846020838601011115614ce257600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215614d1257600080fd5b614d1b83614b9e565b915060208301356001600160401b03811115614d3657600080fd5b614d4285828601614ca9565b9150509250929050565b600080600060608486031215614d6157600080fd5b833592506020840135614d7381614b5d565b9150614d8160408501614b9e565b90509250925092565b600080600060608486031215614d9f57600080fd5b8335614daa81614b5d565b92506020840135614dba81614b5d565b929592945050506040919091013590565b60008060408385031215614dde57600080fd5b823591506020830135614df081614bb4565b809150509250929050565b60008060408385031215614e0e57600080fd5b50508035926020909101359150565b600060208284031215614e2f57600080fd5b8135610f0181614b5d565b8035601a8110610ab057600080fd5b600060208284031215614e5b57600080fd5b610f0182614e3a565b60008060408385031215614e7757600080fd5b8235614e8281614b5d565b9150614e9060208401614e3a565b90509250929050565b60006001600160401b03821115614eb257614eb2614c13565b5060051b60200190565b600082601f830112614ecd57600080fd5b81356020614edd614cc883614e99565b82815260059290921b84018101918181019086841115614efc57600080fd5b8286015b84811015614f1e57614f1181614e3a565b8352918301918301614f00565b509695505050505050565b600060208284031215614f3b57600080fd5b81356001600160401b03811115614f5157600080fd5b6108e184828501614ebc565b803560ff81168114610ab057600080fd5b60008060408385031215614f8157600080fd5b82356001600160401b0380821115614f9857600080fd5b908401906102408287031215614fad57600080fd5b614fb5614c29565b614fbe83614f5d565b8152614fcc60208401614f5d565b6020820152614fdd60408401614f5d565b6040820152614fee60608401614f5d565b6060820152614fff60808401614f5d565b608082015261501060a08401614f5d565b60a082015261502160c08401614f5d565b60c082015261503260e08401614f5d565b60e0820152610100615045818501614f5d565b90820152610120615057848201614f5d565b90820152610140615069848201614f5d565b9082015261016061507b848201614f5d565b9082015261018061508d848201614f5d565b908201526101a061509f848201614f5d565b908201526101c083810135838111156150b757600080fd5b6150c389828701614ca9565b8284015250506101e080840135838111156150dd57600080fd5b6150e989828701614ca9565b828401525050610200808401358381111561510357600080fd5b61510f89828701614ca9565b828401525050610220808401358381111561512957600080fd5b61513589828701614ca9565b82840152505080945050602085013591508082111561515357600080fd5b50614d4285828601614ca9565b6020815261517460208201835160ff169052565b6000602083015161518a604084018260ff169052565b50604083015160ff8116606084015250606083015160ff8116608084015250608083015160ff811660a08401525060a083015160ff811660c08401525060c083015160ff811660e08401525060e08301516101006151ec8185018360ff169052565b84015190506101206152028482018360ff169052565b84015190506101406152188482018360ff169052565b840151905061016061522e8482018360ff169052565b84015190506101806152448482018360ff169052565b84015190506101a061525a8482018360ff169052565b84015190506101c06152708482018360ff169052565b808501519150506102406101e08181860152615290610260860184614b1e565b9250808601519050601f196102008187860301818801526152b18584614b1e565b9450808801519250506102208187860301818801526152d08584614b1e565b9088015187820390920184880152935090506143388382614b1e565b6000602082840312156152fe57600080fd5b8135610f0181614bb4565b6000806040838503121561531c57600080fd5b823561532781614b5d565b91506020830135614df081614bb4565b6000806000806080858703121561534d57600080fd5b843561535881614b5d565b9350602085013561536881614b5d565b92506040850135915060608501356001600160401b0381111561538a57600080fd5b61539687828801614ca9565b91505092959194509250565b60008083601f8401126153b457600080fd5b5081356001600160401b038111156153cb57600080fd5b6020830191508360208260051b850101111561115357600080fd5b6000806000806000606086880312156153fe57600080fd5b8535945060208601356001600160401b038082111561541c57600080fd5b61542889838a016153a2565b9096509450604088013591508082111561544157600080fd5b5061544e888289016153a2565b969995985093965092949392505050565b6000806040838503121561547257600080fd5b82356001600160401b038082111561548957600080fd5b818501915085601f83011261549d57600080fd5b813560206154ad614cc883614e99565b82815260059290921b840181019181810190898411156154cc57600080fd5b948201945b838610156154f35785356154e481614b5d565b825294820194908201906154d1565b9650508601359250508082111561550957600080fd5b50614d4285828601614ebc565b6000806040838503121561552957600080fd5b823561553481614b5d565b91506020830135614df081614b5d565b6000806020838503121561555757600080fd5b82356001600160401b038082111561556e57600080fd5b818501915085601f83011261558257600080fd5b81358181111561559157600080fd5b8660208285010111156155a357600080fd5b60209290920196919550909350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a0a57610a0a6155cb565b80820180821115610a0a57610a0a6155cb565b602080825260149082015273756e7265636f676e697a6564206c61776c65737360601b604082015260600190565b600181811c9082168061564d57607f821691505b6020821081036109c257634e487b7160e01b600052602260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600f908201526e75736572206c61636b7320726f6c6560881b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60006020828403121561572e57600080fd5b8151610f0181614b5d565b60006020828403121561574b57600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b6020808252600c908201526b155b985d5d1a1bdc9a5e995960a21b604082015260600190565b6000600182016157a0576157a06155cb565b5060010190565b6020808252600f908201526e1a5b9d985b1a59081d1bdad95b9259608a1b604082015260600190565b634e487b7160e01b600052601260045260246000fd5b6000826157f5576157f56157d0565b500490565b6000615808614cc884614c82565b905082815283838301111561581c57600080fd5b610f01836020830184614afa565b60006020828403121561583c57600080fd5b81516001600160401b0381111561585257600080fd5b8201601f8101841361586357600080fd5b6108e1848251602084016157fa565b6040815260066040820152651b5a5b9d195960d21b6060820152608060208201526000610f016080830184614b1e565b600081516158b4818560208601614afa565b9290920192915050565b600084516158d0818460208901614afa565b8083019050600b60fa1b80825285516158f0816001850160208a01614afa565b6001920191820152835161590b816002840160208801614afa565b0160020195945050505050565b60006020828403121561592a57600080fd5b610f0182614b9e565b61181760f11b815260008251615950816002850160208701614afa565b602560f81b6002939091019283015250600301919050565b828482376000838201600081528351615985818360208801614afa565b0195945050505050565b6000602082840312156159a157600080fd5b8151610f0181614bb4565b600061ffff8083168181036159c3576159c36155cb565b6001019392505050565b81810381811115610a0a57610a0a6155cb565b6000826159ef576159ef6157d0565b500690565b61ffff81811683821601908082111561113a5761113a6155cb565b600061ffff821680615a2357615a236155cb565b6000190192915050565b61ffff82811682821603908082111561113a5761113a6155cb565b60008351615a5a818460208801614afa565b835190830190615a6e818360208801614afa565b01949350505050565b600088516020615a8a8285838e01614afa565b895191840191615a9d8184848e01614afa565b8951920191615aaf8184848d01614afa565b8851920191615ac18184848c01614afa565b8751920191615ad38184848b01614afa565b8651920191615ae58184848a01614afa565b8551920191615af78184848901614afa565b919091019a9950505050505050505050565b7519185d184e9a5b5859d94bd9da598ed8985cd94d8d0b60521b815260008251615b3a816016850160208701614afa565b9190910160160192915050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b65ffffffffffff81811683821601908082111561113a5761113a6155cb565b65ffffffffffff82811682821603908082111561113a5761113a6155cb565b805160208201516001600160f01b0319808216929190600283101561276f5760029290920360031b82901b161692915050565b60ff8181168382160190811115610a0a57610a0a6155cb565b60ff8281168282160390811115610a0a57610a0a6155cb565b60f884901b6001600160f81b031916815260f083901b6001600160f01b03191660018201528151600090615c77816003850160208701614afa565b91909101600301949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061433890830184614b1e565b600060208284031215615ccb57600080fd5b8151610f0181614ac7565b6000815260008251615cef816001850160208701614afa565b9190910160010192915050565b6a600b5981380380925939f360a81b81528151600090615d2381600b850160208701614afa565b91909101600b0192915050565b6001600160f81b031960f88f811b821683528e811b821660018401528d811b821660028401528c811b821660038401528b811b821660048401528a811b8216600584015289901b166006820152615d96600782018860f81b6001600160f81b0319169052565b615daf600882018760f81b6001600160f81b0319169052565b6000615dbe60098301876158a2565b615dd4818760f81b6001600160f81b0319169052565b615de160018201866158a2565b9050615df9818560f81b6001600160f81b0319169052565b6001019f9e505050505050505050505050505050565b6001600160d01b03198a1681526001600160f81b031960f88a811b8216600684015289811b8216600784015288811b8216600884015287901b1660098201528451600090615e6481600a850160208a01614afa565b6cffffffffffffffffffffffffff198616600a918401918201528451615e9181601d840160208901614afa565b01615ea8601d8201856001600160f81b0319169052565b601e019b9a5050505050505050505050565b6001600160d01b03198a1681526001600160f81b031960f88a811b8216600684015289811b8216600784015288811b8216600884015287901b1660098201528451600090615f0f81600a850160208a01614afa565b855190830190615f2681600a840160208a01614afa565b8551910190615f3c81600a840160208901614afa565b01615f53600a8201856001600160f81b0319169052565b600b019b9a505050505050505050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220b45e9e38cc3d6f3c2ceeeeff99a447fa59347470523267024624e1ec17972edb64736f6c63430008120033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000000000000000000000000000000000004

-----Decoded View---------------
Arg [0] : tokenId (uint256): 4

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000004


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ 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.