ETH Price: $3,459.75 (-0.67%)
Gas: 3 Gwei

Token

lawless (🏴)
 

Overview

Max Total Supply

1,889 🏴

Holders

497

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
chuchunav.eth
Balance
4 🏴
0xe8d7e2f495c77da1d4083070229f26c8cf0fb3b2
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

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 : 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 2 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 3 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 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


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.