ETH Price: $3,416.38 (-0.65%)
Gas: 2 Gwei

Token

Blitblox (BX)
 

Overview

Max Total Supply

0 BX

Holders

62

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
pipilu.eth
Balance
1 BX
0x4c55c41bd839b3552fb2abecacfdf4a5d2879cb9
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:
Blitblox

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 800 runs

Other Settings:
default evmVersion
File 1 of 16 : Blitblox.sol
// SPDX-License-Identifier: MIT

/*
    B L I T B L 0 x
    L \           L \
    I   B L I T B L 0 x
    T   L         T   L
    B   I    <3   B   I
    L   T         L   T
    0   B         0   B
    B L L T B L 0 x   L
      \ 0           \ 0
        B L I T B L 0 x
    
    Blitblox
    by sayangel.eth
    Derivative project for Blitmap and Flipmap.
    Experimenting with 3D glTF on chain.
*/
pragma solidity >=0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/interfaces/IERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import '@openzeppelin/contracts/utils/Strings.sol';
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

import "./IBlitmap.sol";
import "./IFlipmap.sol";

contract Blitblox is ERC721, Ownable, ReentrancyGuard {
    struct glTFCursor {
        uint8 x;
        uint8 y;
        uint256 color1;
        uint256 color2;
        uint256 color3;
        uint256 color4;
    }

    uint256 private constant PRECISION_MULTIPLIER = 1000;

    uint256 private _mintPrice = 0.02 ether;
    
    string private _proxyUri;

    mapping(uint256 => bytes1) private _tokenStyles;

    mapping(address => uint256) private _creators;

    IFlipmap flipmap;
    IBlitmap blitmap;

    modifier onlyCreators() {
        require(isCreator(msg.sender));
        _;
    }

    constructor(address _blitAddress, address _flipAddress) ERC721("Blitblox", "BX") Ownable() {
        blitmap = IBlitmap(_blitAddress);
        flipmap = IFlipmap(_flipAddress);
    }

    function tokenURI(uint256 tokenId) override(ERC721) public view returns (string memory) {
        //wrap the original SVG in an anaglyph style filter
        string memory svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 32 32"><filter id="i1" width="150%" height="150%"><feOffset result="offOut" in="SourceGraphic" dx="1" dy="0"/><feOffset result="off2Out" in="SourceGraphic" dx="-1" dy="0"/><feColorMatrix result="matrixOut" in="offOut" type="matrix" values="0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.4 0"/><feColorMatrix result="matrix2Out" in="off2Out" type="matrix" values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.4 0"/><feBlend result="blend1" in="matrix2Out" in2="SourceGraphic" mode="normal"/><feBlend in="matrixOut" in2="blend1" mode="normal"/></filter><g filter="url(#i1)"><image width="100%" height="100%" href="data:image/svg+xml;base64,';
        
        if(tokenId < 1700)
            svg = string(abi.encodePacked(svg, Base64.encode(bytes(blitmap.tokenSvgDataOf(tokenId)))));
        else
            svg = string(abi.encodePacked(svg, Base64.encode(bytes(flipmap.tokenSvgDataOf(tokenId)))));
        
        svg = string(abi.encodePacked(svg, '"/></g></svg>'));
        svg = string(abi.encodePacked('data:image/svg+xml;base64,', Base64.encode(bytes(svg))));

        string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "Blitblox #', Strings.toString(tokenId), '", "description": "Blitblox is a derivative project of Blitmap and Flipmap. It generates a three dimensional voxel version of the corresponding map. All 3D data is generated and stored on chain as a glTF.", "image":"', svg, '","animation_url":"', _proxyUri, Strings.toString(tokenId),'.glb"}'))));
        return string(abi.encodePacked('data:application/json;base64,', json));
    }

    /*  
    *   As of Jan 2022 OS and other platforms with glTF support expect a glb via HTTP response.
    *   hack around this by returning the contract response via an HTTP proxy that 
    *   calls tokenGltfDataOf() and returns response.
    */
    function setProxyUri(string memory proxyUri) public onlyOwner {
        _proxyUri = proxyUri;
    }

    function mint(uint256 tokenId, bytes1 style) external payable nonReentrant {
        require(_mintPrice == msg.value);

        if(tokenId < 1700)
            require(blitmap.ownerOf(tokenId) == msg.sender);
        else
            require(flipmap.ownerOf(tokenId) == msg.sender);

        address creatorA = owner();
        address creatorB = owner();

        //artist gets full royalties on original
        if(tokenId < 100) { 
            creatorA = blitmap.tokenCreatorOf(tokenId);
            creatorB = blitmap.tokenCreatorOf(tokenId);
        }

        //siblings and flipmaps divide royalties between composition and pallette artist
        if(tokenId > 99) { 
            uint256 tokenIdA;
            uint256 tokenIdB;
            if(tokenId < 1700 ){
                (tokenIdA, tokenIdB) = blitmap.tokenParentsOf(tokenId);
            }
            else 
                (tokenIdA, tokenIdB) = flipmap.tokenParentsOf(tokenId);

            creatorA = blitmap.tokenCreatorOf(tokenIdA);
            creatorB = blitmap.tokenCreatorOf(tokenIdB);
        }

        _tokenStyles[tokenId] = style;
        _safeMint(msg.sender, tokenId);

        // 25% royalty to original artists. 
        // of that, 75% to composition artist and 25% to palette artist.
        _creators[creatorA]     +=  0.00375 ether;
        _creators[creatorB]     += 0.00125 ether;
        _creators[owner()]      += 0.015 ether;
    }

    function isCreator(address _address) public view returns (bool) {
        return _creators[_address] > 0;
    }

    function availableBalanceForCreator(address creatorAddress) public view returns (uint256) {
        return _creators[creatorAddress];
    }

    function withdrawAvailableBalance() public nonReentrant onlyCreators {
        uint256 withdrawAmount = _creators[msg.sender];
        _creators[msg.sender] = 0;
        payable(msg.sender).transfer(withdrawAmount);
    }

    function voxel4(string[32] memory lookup, glTFCursor memory pos) internal pure returns (string memory) {
        return string(abi.encodePacked(
            '{"mesh":', Strings.toString(pos.color1), ',"translation": [', lookup[pos.x], ', 0.0,', lookup[31 - pos.y],']},',
            '{"mesh":', Strings.toString(pos.color2), ',"translation": [', lookup[pos.x + 1], ', 0.0,', lookup[31 - pos.y],']},',

            string(abi.encodePacked(
                '{"mesh":', Strings.toString(pos.color3), ',"translation": [', lookup[pos.x + 2], ', 0.0,', lookup[31 - pos.y],']},',
                '{"mesh":', Strings.toString(pos.color4), ',"translation": [', lookup[pos.x + 3], ', 0.0,', lookup[31- pos.y],']}'
            ))
        )) ;
    }

    function bitTest(bytes1 aByte, uint8 index) internal pure returns (bool) {
        return uint8(aByte) >> index & 1 == 1;
    }

    function colorIndex(bytes1 aByte, uint8 index1, uint8 index2) internal pure returns (uint) {
        if (bitTest(aByte, index2) && bitTest(aByte, index1)) {
            return 3;
        } else if (bitTest(aByte, index2) && !bitTest(aByte, index1)) {
            return 2;
        } else if (!bitTest(aByte, index2) && bitTest(aByte, index1)) {
            return 1;
        }
        return 0;
    }

    function styleByteToInts(bytes1 style) internal pure returns (uint8, uint8) {
        /* 
        *   decode the style of a given token.
        *    first 4 bits  represent the voxel style:
        *        0 - normal
        *        1 - normal with transparency
        *        2 - exploded
        *        3 - exploded with transparency
        *    last 4 bits represent the color index to apply transparency to. Value between 0-3.
        */

        return (uint8(style >> 4), uint8(style & hex"0F"));
    }

    /*function setTokenStyle(uint256 tokenId, bytes1 style) public {
        require(ownerOf(tokenId) == msg.sender, "This wallet does not own this Blitblox."); 
        _tokenStyles[tokenId] = style;
    }

    function getTokenStyle (uint256 tokenId) public view returns (uint8, uint8) {
        return styleByteToInts(_tokenStyles[tokenId]);
    }*/

    //returns an approximation of the original RGB value in sRGB color space. 
    function intRGBValTosRGBVal(uint256 val) internal pure returns (string memory result) {
        uint256 res = (val * PRECISION_MULTIPLIER) * (PRECISION_MULTIPLIER * PRECISION_MULTIPLIER) / (255 * PRECISION_MULTIPLIER);
        res = (res ** 2)/( PRECISION_MULTIPLIER * PRECISION_MULTIPLIER);
        string memory sRGBString = string( abi.encodePacked(bytes(Strings.toString(uint(res/( PRECISION_MULTIPLIER * PRECISION_MULTIPLIER)))), bytes(".")));   
        sRGBString = string(abi.encodePacked(sRGBString, bytes( Strings.toString( res % ( PRECISION_MULTIPLIER * PRECISION_MULTIPLIER) / 100000 ) ) ) );
        sRGBString = string(abi.encodePacked(sRGBString, bytes( Strings.toString( res % ( PRECISION_MULTIPLIER * PRECISION_MULTIPLIER / 10) / 10000 ) ) ) );
        sRGBString = string(abi.encodePacked(sRGBString, bytes( Strings.toString( res % ( PRECISION_MULTIPLIER * PRECISION_MULTIPLIER / 100) / 1000 ) ) ) );
        return sRGBString;
    }

    function tokenGltfDataOf(uint256 tokenId) public view returns (string memory) {
        bytes memory data;
        if(tokenId < 1700 ) {
            data = blitmap.tokenDataOf(tokenId);
        }
        else {
            data = flipmap.tokenDataOf(tokenId);
        }
        return tokenGltfData(data, _tokenStyles[tokenId]);
    }

    /*
    *   glTF data built from blitmap/flipmap token data. Just like original SVGs data is built in chunks of 4 voxels at a time.
    *   The output is a 32 x 32 grid of voxels. Each voxel is a node in the scene that references 1 of 4 meshes depending on its color. 
    *   There are 4 mesh primitives with the only difference being material index. There is only one mesh buffer: a voxel/cube. 
    *   Voxel spacing and material transparency are affected by the tokens saved style.
    */
    function tokenGltfData(bytes memory data, bytes1 style) public pure returns (string memory) {
        (uint8 voxelStyle, uint8 transparencyIndex) = styleByteToInts(style);

        string[32] memory lookup = [
        "0", "1", "2", "3", "4", "5", "6", "7",
        "8", "9", "10", "11", "12", "13", "14", "15",
        "16", "17", "18", "19", "20", "21", "22", "23",
        "24", "25", "26", "27", "28", "29", "30", "31"
        ];

        glTFCursor memory pos;

        uint256[3][4] memory colors = [
        [byteToUint(data[0]), byteToUint(data[1]), byteToUint(data[2])],
        [byteToUint(data[3]), byteToUint(data[4]), byteToUint(data[5])],
        [byteToUint(data[6]), byteToUint(data[7]), byteToUint(data[8])],
        [byteToUint(data[9]), byteToUint(data[10]), byteToUint(data[11])]
        ];

        string[8] memory p;

        string memory gltfAccumulator = '{"asset": {"generator": "Blitblox.sol","version": "2.0"},"scene": 0,"scenes": [{"nodes": [0]}],';
        gltfAccumulator = strConcat(gltfAccumulator, '"nodes": [{"children": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024],');
        gltfAccumulator = strConcat(gltfAccumulator, '"matrix": [1.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,1.0]},');
        for (uint i = 12; i < 268; i += 8) {
            pos.color1 =  colorIndex(data[i], 6, 7);
            pos.color2 =  colorIndex(data[i], 4, 5);
            pos.color3 =  colorIndex(data[i], 2, 3);
            pos.color4 =  colorIndex(data[i], 0, 1);
            p[0] = voxel4(lookup, pos);
            p[0] = strConcat(p[0], ',');
            pos.x += 4;
            
            pos.color1 =  colorIndex(data[i + 1], 6, 7);
            pos.color2 =  colorIndex(data[i + 1], 4, 5);
            pos.color3 =  colorIndex(data[i + 1], 2, 3);
            pos.color4 =  colorIndex(data[i + 1], 0, 1);
            p[1] = voxel4(lookup, pos);
            p[1] = strConcat(p[1], ',');
            pos.x += 4;
            
            pos.color1 =  colorIndex(data[i + 2], 6, 7);
            pos.color2 =  colorIndex(data[i + 2], 4, 5);
            pos.color3 =  colorIndex(data[i + 2], 2, 3);
            pos.color4 =  colorIndex(data[i + 2], 0, 1);
            p[2] = voxel4(lookup, pos);
            p[2] = strConcat(p[2], ',');
            pos.x += 4;
            
            pos.color1 =  colorIndex(data[i + 3], 6, 7);
            pos.color2 =  colorIndex(data[i + 3], 4, 5);
            pos.color3 =  colorIndex(data[i + 3], 2, 3);
            pos.color4 =  colorIndex(data[i + 3], 0, 1);
            p[3] = voxel4(lookup, pos);
            p[3] = strConcat(p[3], ',');
            pos.x += 4;
            
            pos.color1 =  colorIndex(data[i + 4], 6, 7);
            pos.color2 =  colorIndex(data[i + 4], 4, 5);
            pos.color3 =  colorIndex(data[i + 4], 2, 3);
            pos.color4 =  colorIndex(data[i + 4], 0, 1);
            p[4] = voxel4(lookup, pos);
            p[4] = strConcat(p[4], ',');
            pos.x += 4;
            
            pos.color1 =  colorIndex(data[i + 5], 6, 7);
            pos.color2 =  colorIndex(data[i + 5], 4, 5);
            pos.color3 =  colorIndex(data[i + 5], 2, 3);
            pos.color4 =  colorIndex(data[i + 5], 0, 1);
            p[5] = voxel4(lookup, pos);
            p[5] = strConcat(p[5], ',');
            pos.x += 4;
            
            pos.color1 =  colorIndex(data[i + 6], 6, 7);
            pos.color2 =  colorIndex(data[i + 6], 4, 5);
            pos.color3 =  colorIndex(data[i + 6], 2, 3);
            pos.color4 =  colorIndex(data[i + 6], 0, 1);
            p[6] = voxel4(lookup, pos);
            p[6] = strConcat(p[6], ',');
            pos.x += 4;
            
            pos.color1 =  colorIndex(data[i + 7], 6, 7);
            pos.color2 =  colorIndex(data[i + 7], 4, 5);
            pos.color3 =  colorIndex(data[i + 7], 2, 3);
            pos.color4 =  colorIndex(data[i + 7], 0, 1);
            p[7] = voxel4(lookup, pos);
            if(i + 9 < 268){
                p[7] = strConcat(p[7], ',');
            }
            pos.x += 4;
            
            gltfAccumulator = string(abi.encodePacked(gltfAccumulator, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]));
            
            if (pos.x >= 32) {
                pos.x = 0;
                pos.y += 1;
            }
        }
        gltfAccumulator = strConcat(gltfAccumulator, '],');
        gltfAccumulator = strConcat(gltfAccumulator, '"materials": [');
        for(uint i=0; i < colors.length; i++){
            gltfAccumulator = strConcat(gltfAccumulator,'{"pbrMetallicRoughness": {"baseColorFactor": [');
            gltfAccumulator = string( abi.encodePacked(bytes(gltfAccumulator), bytes(intRGBValTosRGBVal(colors[i][0])), bytes(",") ));
            gltfAccumulator = string( abi.encodePacked(bytes(gltfAccumulator), bytes(intRGBValTosRGBVal(colors[i][1])), bytes(",") ));
            gltfAccumulator = string( abi.encodePacked(bytes(gltfAccumulator), bytes(intRGBValTosRGBVal(colors[i][2])), bytes(",") ));
            if(voxelStyle % 2 == 1 && i == transparencyIndex) {
                gltfAccumulator = string( abi.encodePacked(bytes(gltfAccumulator), bytes("0.5")));
            }
            else {
                gltfAccumulator = string( abi.encodePacked(bytes(gltfAccumulator), bytes("1.0")));
            }
            gltfAccumulator = strConcat(gltfAccumulator,'],"metallicFactor": 0.0},');
            if(voxelStyle % 2 == 1 && i == transparencyIndex) {
                gltfAccumulator = strConcat(gltfAccumulator, '"alphaMode": "BLEND",');
            }
            gltfAccumulator = strConcat(gltfAccumulator, '"name": "material"}');
            if(i + 1 < colors.length ){
                gltfAccumulator = strConcat(gltfAccumulator, ',');
            }
        }
        gltfAccumulator = strConcat(gltfAccumulator,'],');
        gltfAccumulator = strConcat(gltfAccumulator, '"meshes": [');
        for(uint i=0; i < colors.length; i++){
            gltfAccumulator = strConcat(gltfAccumulator,'{"primitives": [{"attributes": {"POSITION": 0, "NORMAL": 1},"indices": 2,"material": ');
            gltfAccumulator = strConcat(gltfAccumulator, Strings.toString(i));
            gltfAccumulator = strConcat(gltfAccumulator,'}],"name": "Mesh');
            gltfAccumulator = strConcat(gltfAccumulator, Strings.toString(i));
            gltfAccumulator = strConcat(gltfAccumulator,'"}');
            if(i + 1 < colors.length ){
                gltfAccumulator = strConcat(gltfAccumulator, ',');
            }
        }

        gltfAccumulator = strConcat(gltfAccumulator,'],');
        gltfAccumulator = strConcat(gltfAccumulator, '"accessors": [');
        gltfAccumulator = strConcat(gltfAccumulator, '{"bufferView" : 0,"componentType" : 5126,"count" : 24,"max" : [0.5,0.5,0.5],"min" : [-0.5,-0.5,-0.5],"type" : "VEC3"},');
        gltfAccumulator = strConcat(gltfAccumulator, '{"bufferView" : 1,"componentType" : 5126,"count" : 24,"type" : "VEC3"},');
        gltfAccumulator = strConcat(gltfAccumulator, '{"bufferView" : 2,"componentType" : 5123,"count" : 36,"type" : "SCALAR"}');
        gltfAccumulator = strConcat(gltfAccumulator, '],');
        gltfAccumulator = strConcat(gltfAccumulator, '"bufferViews": [');
        gltfAccumulator = strConcat(gltfAccumulator, '{"buffer" : 0,"byteLength" : 288,"byteOffset" : 0},');
        gltfAccumulator = strConcat(gltfAccumulator, '{"buffer" : 0,"byteLength" : 288,"byteOffset" : 288},');
        gltfAccumulator = strConcat(gltfAccumulator, '{"buffer" : 0,"byteLength" : 72,"byteOffset" : 576}');
        gltfAccumulator = strConcat(gltfAccumulator, '],');
        gltfAccumulator = strConcat(gltfAccumulator, '"buffers": [{"byteLength": 648,"uri": "data:application/octet-stream;base64,');

        //the strings below are the buffers for a voxel's vertex data.
        //every node refers to a mesh described by this same buffer.
        //initially I had a single buffer and applied a scale transform to every node depdnding on style
        //but this was inefficient and caused a 4x bigger payload and longer execution time.
        //when the "exploded" style is chosen the buffer is modified to be a smaller voxel.
        //index and normal buffers are the same regardless of style.
        if(voxelStyle < 2){
            gltfAccumulator = strConcat(gltfAccumulator, 'AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/');
        } else {
            gltfAccumulator = strConcat(gltfAccumulator, 'AADAvgAAwL4AAMA+AADAPgAAwL4AAMA+AADAvgAAwD4AAMA+AADAPgAAwD4AAMA+AADAPgAAwL4AAMA+AADAvgAAwL4AAMA+AADAPgAAwL4AAMC+AADAvgAAwL4AAMC+AADAPgAAwD4AAMA+AADAPgAAwL4AAMA+AADAPgAAwD4AAMC+AADAPgAAwL4AAMC+AADAvgAAwD4AAMA+AADAPgAAwD4AAMA+AADAvgAAwD4AAMC+AADAPgAAwD4AAMC+AADAvgAAwL4AAMA+AADAvgAAwD4AAMA+AADAvgAAwL4AAMC+AADAvgAAwD4AAMC+AADAvgAAwL4AAMC+AADAvgAAwD4AAMC+AADAPgAAwL4AAMC+AADAPgAAwD4AAMC+');
        }
        gltfAccumulator = strConcat(gltfAccumulator, 'AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAACAPwAAAAAAAACAAACAPwAAAAAAAACAAACAPwAAAAAAAACAAACAPwAAAAAAAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAACAvwAAAAAAAACAAACAvwAAAAAAAACAAACAvwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA"}]');
        gltfAccumulator = strConcat(gltfAccumulator, '}');
        return gltfAccumulator;
    }

    function byteToUint(bytes1 b) internal pure returns (uint256) {
        return uint256(uint8(b));
    }

    function strConcat(string memory _a, string memory _b) internal pure returns (string memory result) {
        result = string(abi.encodePacked(bytes(_a), bytes(_b)));
    }
}

/// [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 2 of 16 : ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, 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;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

File 3 of 16 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../token/ERC721/extensions/IERC721Enumerable.sol";

File 4 of 16 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 5 of 16 : Strings.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

File 6 of 16 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 7 of 16 : IBlitmap.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

interface IBlitmap{
    function ownerOf(uint256 tokenId) external view returns (address);
    function tokenCreatorOf(uint256 tokenId) external view returns (address);
    function tokenDataOf(uint256 tokenId) external view returns (bytes memory) ;
    function tokenParentsOf(uint256 tokenId) external view returns (uint256, uint256);
    function tokenSvgDataOf(uint256 tokenId) external view returns (string memory);
}

File 8 of 16 : IFlipmap.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

interface IFlipmap{
    function ownerOf(uint256 tokenId) external view returns (address);
    function tokenDataOf(uint256 tokenId) external view returns (bytes memory) ;
    function tokenParentsOf(uint256 tokenId) external view returns (uint256, uint256);
    function tokenSvgDataOf(uint256 tokenId) external view returns (string memory);
}

File 9 of 16 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

File 10 of 16 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT

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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 11 of 16 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 12 of 16 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 13 of 16 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 14 of 16 : ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

File 15 of 16 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 16 of 16 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_blitAddress","type":"address"},{"internalType":"address","name":"_flipAddress","type":"address"}],"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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"creatorAddress","type":"address"}],"name":"availableBalanceForCreator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isCreator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes1","name":"style","type":"bytes1"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"proxyUri","type":"string"}],"name":"setProxyUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes1","name":"style","type":"bytes1"}],"name":"tokenGltfData","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenGltfDataOf","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAvailableBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405266470de4df8200006008553480156200001c57600080fd5b5060405162006289380380620062898339810160408190526200003f916200020c565b6040805180820182526008815267084d8d2e8c4d8def60c31b602080830191825283518085019094526002845261084b60f31b908401528151919291620000899160009162000149565b5080516200009f90600190602084019062000149565b505050620000bc620000b6620000f360201b60201c565b620000f7565b6001600755600d80546001600160a01b039384166001600160a01b031991821617909155600c805492909316911617905562000281565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001579062000244565b90600052602060002090601f0160209004810192826200017b5760008555620001c6565b82601f106200019657805160ff1916838001178555620001c6565b82800160010185558215620001c6579182015b82811115620001c6578251825591602001919060010190620001a9565b50620001d4929150620001d8565b5090565b5b80821115620001d45760008155600101620001d9565b80516001600160a01b03811681146200020757600080fd5b919050565b600080604083850312156200022057600080fd5b6200022b83620001ef565b91506200023b60208401620001ef565b90509250929050565b600181811c908216806200025957607f821691505b602082108114156200027b57634e487b7160e01b600052602260045260246000fd5b50919050565b615ff880620002916000396000f3fe6080604052600436106101805760003560e01c80638da5cb5b116100d6578063c87b56dd1161007f578063e985e9c511610059578063e985e9c51461042a578063efd4606514610473578063f2fde38b146104ab57600080fd5b8063c87b56dd146103d7578063d0b23ba4146103f7578063e0e0daea1461041757600080fd5b8063a22cb465116100b0578063a22cb46514610382578063b1111359146103a2578063b88d4fde146103b757600080fd5b80638da5cb5b146103195780638e13a1461461033757806395d89b411461036d57600080fd5b80632fde60a0116101385780636352211e116101125780636352211e146102b657806370a08231146102d6578063715018a61461030457600080fd5b80632fde60a01461025657806342842e0e146102765780635b9a19d01461029657600080fd5b8063081812fc11610169578063081812fc146101dc578063095ea7b31461021457806323b872dd1461023657600080fd5b806301ffc9a71461018557806306fdde03146101ba575b600080fd5b34801561019157600080fd5b506101a56101a036600461376a565b6104cb565b60405190151581526020015b60405180910390f35b3480156101c657600080fd5b506101cf61051d565b6040516101b191906137df565b3480156101e857600080fd5b506101fc6101f73660046137f2565b6105af565b6040516001600160a01b0390911681526020016101b1565b34801561022057600080fd5b5061023461022f366004613820565b610649565b005b34801561024257600080fd5b5061023461025136600461384c565b61075f565b34801561026257600080fd5b5061023461027136600461393a565b6107e6565b34801561028257600080fd5b5061023461029136600461384c565b610857565b3480156102a257600080fd5b506101cf6102b13660046139c0565b610872565b3480156102c257600080fd5b506101fc6102d13660046137f2565b611b7a565b3480156102e257600080fd5b506102f66102f1366004613a0e565b611c05565b6040519081526020016101b1565b34801561031057600080fd5b50610234611c9f565b34801561032557600080fd5b506006546001600160a01b03166101fc565b34801561034357600080fd5b506102f6610352366004613a0e565b6001600160a01b03166000908152600b602052604090205490565b34801561037957600080fd5b506101cf611d05565b34801561038e57600080fd5b5061023461039d366004613a2b565b611d14565b3480156103ae57600080fd5b50610234611dd9565b3480156103c357600080fd5b506102346103d2366004613a69565b611e94565b3480156103e357600080fd5b506101cf6103f23660046137f2565b611f22565b34801561040357600080fd5b506101cf6104123660046137f2565b612113565b610234610425366004613ad5565b61224e565b34801561043657600080fd5b506101a5610445366004613af8565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561047f57600080fd5b506101a561048e366004613a0e565b6001600160a01b03166000908152600b6020526040902054151590565b3480156104b757600080fd5b506102346104c6366004613a0e565b612818565b60006001600160e01b031982166380ac58cd60e01b14806104fc57506001600160e01b03198216635b5e139f60e01b145b8061051757506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461052c90613b26565b80601f016020809104026020016040519081016040528092919081815260200182805461055890613b26565b80156105a55780601f1061057a576101008083540402835291602001916105a5565b820191906000526020600020905b81548152906001019060200180831161058857829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661062d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061065482611b7a565b9050806001600160a01b0316836001600160a01b031614156106c25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610624565b336001600160a01b03821614806106de57506106de8133610445565b6107505760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610624565b61075a83836128fa565b505050565b6107693382612968565b6107db5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610624565b61075a838383612a5f565b6006546001600160a01b031633146108405760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610624565b8051610853906009906020840190613693565b5050565b61075a83838360405180602001604052806000815250611e94565b606060008060fc84901c600f60f886901c16604080516104408101825260016104008201818152600360fc1b610420840152825282518084018452818152603160f81b6020828101919091528084019190915283518085018552828152601960f91b818301528385015283518085018552828152603360f81b8183015260608085019190915284518086018652838152600d60fa1b8184015260808086019190915285518087018752848152603560f81b8185015260a08087019190915286518088018852858152601b60f91b8186015260c08088019190915287518089018952868152603760f81b8187015260e088015287518089018952868152600760fb1b8187015261010088015287518089018952958652603960f81b8686015261012087019590955286518088018852600280825261031360f41b828701526101408801919091528751808901895281815261313160f01b818701526101608801528751808901895281815261189960f11b818701526101808801528751808901895281815261313360f01b818701526101a088015287518089018952818152610c4d60f21b818701526101c08801528751808901895281815261313560f01b818701526101e08801528751808901895281815261189b60f11b818701526102008801528751808901895281815261313760f01b818701526102208801528751808901895281815261062760f31b818701526102408801528751808901895281815261313960f01b818701526102608801528751808901895281815261032360f41b818701526102808801528751808901895281815261323160f01b818701526102a08801528751808901895281815261191960f11b818701526102c08801528751808901895281815261323360f01b818701526102e088015287518089018952818152610c8d60f21b818701526103008801528751808901895281815261323560f01b818701526103208801528751808901895281815261191b60f11b818701526103408801528751808901895281815261323760f01b818701526103608801528751808901895281815261064760f31b818701526103808801528751808901895281815261323960f01b818701526103a08801528751808901895281815261033360f41b818701526103c08801528751808901895290815261333160f01b818601526103e0870152865194850187526000808652938501849052958401839052908301829052820181905292810192909252929450909250600060405180608001604052806040518060600160405280610c438c600081518110610c3857610c38613b61565b016020015160f81c90565b8152602001610c5e8c600181518110610c3857610c38613b61565b8152602001610c798c600281518110610c3857610c38613b61565b81525081526020016040518060600160405280610ca28c600381518110610c3857610c38613b61565b8152602001610cbd8c600481518110610c3857610c38613b61565b8152602001610cd88c600581518110610c3857610c38613b61565b81525081526020016040518060600160405280610d018c600681518110610c3857610c38613b61565b8152602001610d1c8c600781518110610c3857610c38613b61565b8152602001610d378c600881518110610c3857610c38613b61565b81525081526020016040518060600160405280610d608c600981518110610c3857610c38613b61565b8152602001610d7b8c600a81518110610c3857610c38613b61565b8152602001610d968c600b81518110610c3857610c38613b61565b905290529050610da4613717565b60006040518060800160405280605f8152602001614e22605f91399050610de681604051806110000160405280610fc68152602001614efc610fc69139612c13565b9050610e0a816040518060800160405280604d8152602001615f9f604d9139612c13565b9050600c5b61010c8110156113cd57610e468b8281518110610e2e57610e2e613b61565b01602001516001600160f81b03191660066007612c3f565b60408601528a51610e7b908c9083908110610e6357610e63613b61565b01602001516001600160f81b03191660046005612c3f565b60608601528a51610eb0908c9083908110610e9857610e98613b61565b01602001516001600160f81b03191660026003612c3f565b60808601528a51610ee5908c9083908110610ecd57610ecd613b61565b01602001516001600160f81b03191660006001612c3f565b60a0860152610ef48686612ce6565b8352610f218360005b6020020151604051806040016040528060018152602001600b60fa1b815250612c13565b835284516004908690610f35908390613b8d565b60ff16905250610f5a8b610f4a836001613bb2565b81518110610e2e57610e2e613b61565b6040860152610f7e8b610f6e836001613bb2565b81518110610e6357610e63613b61565b6060860152610fa28b610f92836001613bb2565b81518110610e9857610e98613b61565b6080860152610fc68b610fb6836001613bb2565b81518110610ecd57610ecd613b61565b60a0860152610fd58686612ce6565b6020840152610fe5836001610efd565b602084015284516004908690610ffc908390613b8d565b60ff169052506110118b610f4a836002613bb2565b60408601526110258b610f6e836002613bb2565b60608601526110398b610f92836002613bb2565b608086015261104d8b610fb6836002613bb2565b60a086015261105c8686612ce6565b604084015261106c836002610efd565b604084015284516004908690611083908390613b8d565b60ff169052506110988b610f4a836003613bb2565b60408601526110ac8b610f6e836003613bb2565b60608601526110c08b610f92836003613bb2565b60808601526110d48b610fb6836003613bb2565b60a08601526110e38686612ce6565b60608401526110f3836003610efd565b60608401528451600490869061110a908390613b8d565b60ff1690525061111f8b610f4a836004613bb2565b60408601526111338b610f6e836004613bb2565b60608601526111478b610f92836004613bb2565b608086015261115b8b610fb6836004613bb2565b60a086015261116a8686612ce6565b608084015261117a836004610efd565b608084015284516004908690611191908390613b8d565b60ff169052506111a68b610f4a836005613bb2565b60408601526111ba8b610f6e836005613bb2565b60608601526111ce8b610f92836005613bb2565b60808601526111e28b610fb6836005613bb2565b60a08601526111f18686612ce6565b60a0840152611201836005610efd565b60a084015284516004908690611218908390613b8d565b60ff1690525061122d8b610f4a836006613bb2565b60408601526112418b610f6e836006613bb2565b60608601526112558b610f92836006613bb2565b60808601526112698b610fb6836006613bb2565b60a08601526112788686612ce6565b60c0840152611288836006610efd565b60c08401528451600490869061129f908390613b8d565b60ff169052506112b48b610f4a836007613bb2565b60408601526112c88b610f6e836007613bb2565b60608601526112dc8b610f92836007613bb2565b60808601526112f08b610fb6836007613bb2565b60a08601526112ff8686612ce6565b60e084015261010c611312826009613bb2565b101561132957611323836007610efd565b60e08401525b60048560000181815161133c9190613b8d565b60ff1690525082516020808501516040808701516060880151608089015160a08a015160c08b015160e08c0151955161137b998c999098979101613be6565b60405160208183030381529060405291506020856000015160ff16106113bb5760008552602085018051600191906113b4908390613b8d565b60ff169052505b6113c6600882613bb2565b9050610e0f565b506113f28160405180604001604052806002815260200161174b60f21b815250612c13565b9050611433816040518060400160405280600e81526020017f226d6174657269616c73223a205b000000000000000000000000000000000000815250612c13565b905060005b600481101561176457611463826040518060600160405280602e8152602001615f3c602e9139612c13565b91508161148d85836004811061147b5761147b613b61565b602002015160005b6020020151612e8d565b604051806040016040528060018152602001600b60fa1b8152506040516020016114b993929190613ca7565b6040516020818303038152906040529150816114ec8583600481106114e0576114e0613b61565b60200201516001611483565b604051806040016040528060018152602001600b60fa1b81525060405160200161151893929190613ca7565b60405160208183030381529060405291508161154b85836004811061153f5761153f613b61565b60200201516002611483565b604051806040016040528060018152602001600b60fa1b81525060405160200161157793929190613ca7565b60408051601f198184030181529190529150611594600289613d00565b60ff1660011480156115a857508660ff1681145b156115f1578160405180604001604052806003815260200162302e3560e81b8152506040516020016115db929190613d22565b6040516020818303038152906040529150611631565b81604051806040016040528060038152602001620312e360ec1b81525060405160200161161f929190613d22565b60405160208183030381529060405291505b611670826040518060400160405280601981526020017f5d2c226d6574616c6c6963466163746f72223a20302e307d2c00000000000000815250612c13565b915061167d600289613d00565b60ff16600114801561169157508660ff1681145b156116d8576116d5826040518060400160405280601581526020017f22616c7068614d6f6465223a2022424c454e44222c0000000000000000000000815250612c13565b91505b611717826040518060400160405280601381526020017f226e616d65223a20226d6174657269616c227d00000000000000000000000000815250612c13565b91506004611726826001613bb2565b10156117525761174f82604051806040016040528060018152602001600b60fa1b815250612c13565b91505b8061175c81613d51565b915050611438565b506117898160405180604001604052806002815260200161174b60f21b815250612c13565b90506117ca816040518060400160405280600b81526020017f226d6573686573223a205b000000000000000000000000000000000000000000815250612c13565b905060005b60048110156118d1576117fa8260405180608001604052806055815260200161488360559139612c13565b915061180e8261180983613015565b612c13565b915061184f826040518060400160405280601081526020017f7d5d2c226e616d65223a20224d65736800000000000000000000000000000000815250612c13565b915061185e8261180983613015565b91506118848260405180604001604052806002815260200161227d60f01b815250612c13565b91506004611893826001613bb2565b10156118bf576118bc82604051806040016040528060018152602001600b60fa1b815250612c13565b91505b806118c981613d51565b9150506117cf565b506118f68160405180604001604052806002815260200161174b60f21b815250612c13565b9050611937816040518060400160405280600e81526020017f226163636573736f7273223a205b000000000000000000000000000000000000815250612c13565b905061195b816040518060a00160405280607681526020016148d860769139612c13565b905061197f81604051806080016040528060478152602001615ec260479139612c13565b90506119a381604051806080016040528060488152602001614eb460489139612c13565b90506119c98160405180604001604052806002815260200161174b60f21b815250612c13565b9050611a0a816040518060400160405280601081526020017f226275666665725669657773223a205b00000000000000000000000000000000815250612c13565b9050611a2e81604051806060016040528060338152602001615f0960339139612c13565b9050611a5281604051806060016040528060358152602001615f6a60359139612c13565b9050611a7681604051806060016040528060338152602001614e8160339139612c13565b9050611a9c8160405180604001604052806002815260200161174b60f21b815250612c13565b9050611ac0816040518060800160405280604c8152602001614537604c9139612c13565b905060028760ff161015611afa57611af381604051806101a0016040528061018081526020016145836101809139612c13565b9050611b22565b611b1f81604051806101a0016040528061018081526020016147036101809139612c13565b90505b611b47816040518061022001604052806101e3815260200161494e6101e39139612c13565b9050611b6c81604051806040016040528060018152602001607d60f81b815250612c13565b9a9950505050505050505050565b6000818152600260205260408120546001600160a01b0316806105175760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610624565b60006001600160a01b038216611c835760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610624565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b03163314611cf95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610624565b611d03600061312b565b565b60606001805461052c90613b26565b6001600160a01b038216331415611d6d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610624565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60026007541415611e2c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610624565b6002600755336000908152600b6020526040902054611e4a57600080fd5b336000818152600b6020526040808220805490839055905190929183156108fc02918491818181858888f19350505050158015611e8b573d6000803e3d6000fd5b50506001600755565b611e9e3383612968565b611f105760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610624565b611f1c8484848461317d565b50505050565b60606000604051806102e001604052806102b18152602001614b716102b1913990506106a483101561200157600d5460405163a78d070f60e01b8152600481018590528291611fda916001600160a01b039091169063a78d070f906024015b60006040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611fd59190810190613d9c565b6131fb565b604051602001611feb929190613d22565b604051602081830303815290604052905061205b565b600c5460405163a78d070f60e01b8152600481018590528291612038916001600160a01b039091169063a78d070f90602401611f81565b604051602001612049929190613d22565b60405160208183030381529060405290505b8060405160200161206c9190613de5565b6040516020818303038152906040529050612086816131fb565b6040516020016120969190613e26565b604051602081830303815290604052905060006120e86120b585613015565b8360096120c188613015565b6040516020016120d49493929190613f05565b6040516020818303038152906040526131fb565b9050806040516020016120fb91906140da565b60405160208183030381529060405292505050919050565b6060806106a48310156121a757600d5460405163c0da9bcd60e01b8152600481018590526001600160a01b039091169063c0da9bcd9060240160006040518083038186803b15801561216457600080fd5b505afa158015612178573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526121a09190810190613d9c565b905061222a565b600c5460405163c0da9bcd60e01b8152600481018590526001600160a01b039091169063c0da9bcd9060240160006040518083038186803b1580156121eb57600080fd5b505afa1580156121ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122279190810190613d9c565b90505b6000838152600a602052604090205461224790829060f81b610872565b9392505050565b600260075414156122a15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610624565b600260075560085434146122b457600080fd5b6106a482101561235257600d546040516331a9108f60e11b81526004810184905233916001600160a01b031690636352211e9060240160206040518083038186803b15801561230257600080fd5b505afa158015612316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233a919061411f565b6001600160a01b03161461234d57600080fd5b6123e1565b600c546040516331a9108f60e11b81526004810184905233916001600160a01b031690636352211e9060240160206040518083038186803b15801561239657600080fd5b505afa1580156123aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ce919061411f565b6001600160a01b0316146123e157600080fd5b60006123f56006546001600160a01b031690565b9050600061240b6006546001600160a01b031690565b9050606484101561251257600d546040516306daaebd60e01b8152600481018690526001600160a01b03909116906306daaebd9060240160206040518083038186803b15801561245a57600080fd5b505afa15801561246e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612492919061411f565b600d546040516306daaebd60e01b8152600481018790529193506001600160a01b0316906306daaebd9060240160206040518083038186803b1580156124d757600080fd5b505afa1580156124eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250f919061411f565b90505b606384111561272c576000806106a48610156125ad57600d54604051630d3488e560e41b8152600481018890526001600160a01b039091169063d3488e5090602401604080518083038186803b15801561256b57600080fd5b505afa15801561257f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a3919061413c565b909250905061262e565b600c54604051630d3488e560e41b8152600481018890526001600160a01b039091169063d3488e5090602401604080518083038186803b1580156125f057600080fd5b505afa158015612604573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612628919061413c565b90925090505b600d546040516306daaebd60e01b8152600481018490526001600160a01b03909116906306daaebd9060240160206040518083038186803b15801561267257600080fd5b505afa158015612686573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126aa919061411f565b600d546040516306daaebd60e01b8152600481018490529195506001600160a01b0316906306daaebd9060240160206040518083038186803b1580156126ef57600080fd5b505afa158015612703573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612727919061411f565b925050505b6000848152600a60205260409020805460ff191660f885901c1790556127523385613361565b6001600160a01b0382166000908152600b602052604081208054660d529ae9e860009290612781908490613bb2565b90915550506001600160a01b0381166000908152600b602052604081208054660470de4df8200092906127b5908490613bb2565b9091555066354a6ba7a180009050600b60006127d96006546001600160a01b031690565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008282546128089190613bb2565b9091555050600160075550505050565b6006546001600160a01b031633146128725760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610624565b6001600160a01b0381166128ee5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610624565b6128f78161312b565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061292f82611b7a565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166129e15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610624565b60006129ec83611b7a565b9050806001600160a01b0316846001600160a01b03161480612a275750836001600160a01b0316612a1c846105af565b6001600160a01b0316145b80612a5757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316612a7282611b7a565b6001600160a01b031614612aee5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610624565b6001600160a01b038216612b505760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610624565b612b5b6000826128fa565b6001600160a01b0383166000908152600360205260408120805460019290612b84908490614160565b90915550506001600160a01b0382166000908152600360205260408120805460019290612bb2908490613bb2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60608282604051602001612c28929190613d22565b604051602081830303815290604052905092915050565b6000600160f885901c60ff84161c8116148015612c675750600160f885901c60ff85161c8116145b15612c7457506003612247565b600160f885901c60ff84161c8116148015612c9b5750600160f885901c60ff85161c811614155b15612ca857506002612247565b600160f885901c60ff84161c811614158015612ccf5750600160f885901c60ff85161c8116145b15612cdc57506001612247565b5060009392505050565b6060612cf58260400151613015565b8251849060ff1660208110612d0c57612d0c613b61565b6020020151848460200151601f612d239190614177565b60ff1660208110612d3657612d36613b61565b6020020151612d488560600151613015565b85518790612d57906001613b8d565b60ff1660208110612d6a57612d6a613b61565b6020020151878760200151601f612d819190614177565b60ff1660208110612d9457612d94613b61565b6020020151612da68860800151613015565b88518a90612db5906002613b8d565b60ff1660208110612dc857612dc8613b61565b60200201518a8a60200151601f612ddf9190614177565b60ff1660208110612df257612df2613b61565b6020020151612e048b60a00151613015565b8b518d90612e13906003613b8d565b60ff1660208110612e2657612e26613b61565b60200201518d8d60200151601f612e3d9190614177565b60ff1660208110612e5057612e50613b61565b6020020151604051602001612e6a9695949392919061419a565b60408051601f1981840301815290829052612c289796959493929160200161429b565b60606000612e9e6103e860ff6143a3565b612eaa6103e8806143a3565b612eb66103e8866143a3565b612ec091906143a3565b612eca91906143c2565b9050612ed86103e8806143a3565b612ee36002836144ba565b612eed91906143c2565b90506000612f0f612f006103e8806143a3565b612f0a90846143c2565b613015565b604051806040016040528060018152602001601760f91b815250604051602001612f3a929190613d22565b60408051601f19818403018152919052905080612f74620186a0612f606103e8806143a3565b612f6a90866144c9565b612f0a91906143c2565b604051602001612f85929190613d22565b60408051601f19818403018152919052905080612fb6612710600a612fac6103e8806143a3565b612f6091906143c2565b604051602001612fc7929190613d22565b60408051601f19818403018152919052905080612fec6103e86064612fac82806143a3565b604051602001612ffd929190613d22565b60408051601f19818403018152919052949350505050565b6060816130395750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613063578061304d81613d51565b915061305c9050600a836143c2565b915061303d565b60008167ffffffffffffffff81111561307e5761307e61388d565b6040519080825280601f01601f1916602001820160405280156130a8576020820181803683370190505b5090505b8415612a57576130bd600183614160565b91506130ca600a866144c9565b6130d5906030613bb2565b60f81b8183815181106130ea576130ea613b61565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613124600a866143c2565b94506130ac565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613188848484612a5f565b6131948484848461337b565b611f1c5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610624565b80516060908061321b575050604080516020810190915260008152919050565b6000600361322a836002613bb2565b61323491906143c2565b61323f9060046143a3565b9050600061324e826020613bb2565b67ffffffffffffffff8111156132665761326661388d565b6040519080825280601f01601f191660200182016040528015613290576020820181803683370190505b5090506000604051806060016040528060408152602001614b31604091399050600181016020830160005b8681101561331c576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016132bb565b506003860660018114613336576002811461334757613353565b613d3d60f01b600119830152613353565b603d60f81b6000198301525b505050918152949350505050565b6108538282604051806020016040528060008152506134d3565b60006001600160a01b0384163b156134c857604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906133bf9033908990889088906004016144dd565b602060405180830381600087803b1580156133d957600080fd5b505af1925050508015613409575060408051601f3d908101601f1916820190925261340691810190614519565b60015b6134ae573d808015613437576040519150601f19603f3d011682016040523d82523d6000602084013e61343c565b606091505b5080516134a65760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610624565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612a57565b506001949350505050565b6134dd8383613551565b6134ea600084848461337b565b61075a5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610624565b6001600160a01b0382166135a75760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610624565b6000818152600260205260409020546001600160a01b03161561360c5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610624565b6001600160a01b0382166000908152600360205260408120805460019290613635908490613bb2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461369f90613b26565b90600052602060002090601f0160209004810192826136c15760008555613707565b82601f106136da57805160ff1916838001178555613707565b82800160010185558215613707579182015b828111156137075782518255916020019190600101906136ec565b5061371392915061373f565b5090565b6040518061010001604052806008905b60608152602001906001900390816137275790505090565b5b808211156137135760008155600101613740565b6001600160e01b0319811681146128f757600080fd5b60006020828403121561377c57600080fd5b813561224781613754565b60005b838110156137a257818101518382015260200161378a565b83811115611f1c5750506000910152565b600081518084526137cb816020860160208601613787565b601f01601f19169290920160200192915050565b60208152600061224760208301846137b3565b60006020828403121561380457600080fd5b5035919050565b6001600160a01b03811681146128f757600080fd5b6000806040838503121561383357600080fd5b823561383e8161380b565b946020939093013593505050565b60008060006060848603121561386157600080fd5b833561386c8161380b565b9250602084013561387c8161380b565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156138cc576138cc61388d565b604052919050565b600067ffffffffffffffff8211156138ee576138ee61388d565b50601f01601f191660200190565b600061390f61390a846138d4565b6138a3565b905082815283838301111561392357600080fd5b828260208301376000602084830101529392505050565b60006020828403121561394c57600080fd5b813567ffffffffffffffff81111561396357600080fd5b8201601f8101841361397457600080fd5b612a57848235602084016138fc565b600082601f83011261399457600080fd5b612247838335602085016138fc565b80356001600160f81b0319811681146139bb57600080fd5b919050565b600080604083850312156139d357600080fd5b823567ffffffffffffffff8111156139ea57600080fd5b6139f685828601613983565b925050613a05602084016139a3565b90509250929050565b600060208284031215613a2057600080fd5b81356122478161380b565b60008060408385031215613a3e57600080fd5b8235613a498161380b565b915060208301358015158114613a5e57600080fd5b809150509250929050565b60008060008060808587031215613a7f57600080fd5b8435613a8a8161380b565b93506020850135613a9a8161380b565b925060408501359150606085013567ffffffffffffffff811115613abd57600080fd5b613ac987828801613983565b91505092959194509250565b60008060408385031215613ae857600080fd5b82359150613a05602084016139a3565b60008060408385031215613b0b57600080fd5b8235613b168161380b565b91506020830135613a5e8161380b565b600181811c90821680613b3a57607f821691505b60208210811415613b5b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168060ff03821115613baa57613baa613b77565b019392505050565b60008219821115613bc557613bc5613b77565b500190565b60008151613bdc818560208601613787565b9290920192915050565b60008a51613bf8818460208f01613787565b8a51613c0a8183860160208f01613787565b8a519184010190613c1f818360208e01613787565b8951613c318183850160208e01613787565b8951929091010190613c47818360208c01613787565b8751613c598183850160208c01613787565b8751929091010190613c6f818360208a01613787565b8551613c818183850160208a01613787565b8551929091010190613c97818360208801613787565b019b9a5050505050505050505050565b60008451613cb9818460208901613787565b845190830190613ccd818360208901613787565b8451910190613ce0818360208801613787565b0195945050505050565b634e487b7160e01b600052601260045260246000fd5b600060ff831680613d1357613d13613cea565b8060ff84160691505092915050565b60008351613d34818460208801613787565b835190830190613d48818360208801613787565b01949350505050565b6000600019821415613d6557613d65613b77565b5060010190565b6000613d7a61390a846138d4565b9050828152838383011115613d8e57600080fd5b612247836020830184613787565b600060208284031215613dae57600080fd5b815167ffffffffffffffff811115613dc557600080fd5b8201601f81018413613dd657600080fd5b612a5784825160208401613d6c565b60008251613df7818460208701613787565b7f222f3e3c2f673e3c2f7376673e00000000000000000000000000000000000000920191825250600d01919050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000815260008251613e5e81601a850160208701613787565b91909101601a0192915050565b8054600090600181811c9080831680613e8557607f831692505b6020808410821415613ea757634e487b7160e01b600052602260045260246000fd5b818015613ebb5760018114613ecc57613ef9565b60ff19861689528489019650613ef9565b60008881526020902060005b86811015613ef15781548b820152908501908301613ed8565b505084890196505b50505050505092915050565b7f7b226e616d65223a2022426c6974626c6f782023000000000000000000000000815260008551613f3d816014850160208a01613787565b7f222c20226465736372697074696f6e223a2022426c6974626c6f7820697320616014918401918201527f20646572697661746976652070726f6a656374206f6620426c69746d6170206160348201527f6e6420466c69706d61702e2049742067656e657261746573206120746872656560548201527f2064696d656e73696f6e616c20766f78656c2076657273696f6e206f6620746860748201527f6520636f72726573706f6e64696e67206d61702e20416c6c203344206461746160948201527f2069732067656e65726174656420616e642073746f726564206f6e206368616960b48201527f6e206173206120676c54462e222c2022696d616765223a22000000000000000060d4820152855161405e8160ec840160208a01613787565b6140ce6140a561409f61409960ec858701017f222c22616e696d6174696f6e5f75726c223a2200000000000000000000000000815260130190565b89613e6b565b87613bca565b7f2e676c62227d0000000000000000000000000000000000000000000000000000815260060190565b98975050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161411281601d850160208701613787565b91909101601d0192915050565b60006020828403121561413157600080fd5b81516122478161380b565b6000806040838503121561414f57600080fd5b505080516020909101519092909150565b60008282101561417257614172613b77565b500390565b600060ff821660ff84168082101561419157614191613b77565b90039392505050565b6000673d9136b2b9b4111d60c11b80835288516141be816008860160208d01613787565b8084019050702c227472616e736c6174696f6e223a205b60781b80600883015289516141f1816019850160208e01613787565b650b080c0b8c0b60d21b60199390910192830152885161421881601f850160208d01613787565b80830192505062175f4b60ea1b601f8301528260228301528751925061424583602a840160208b01613787565b828201925080602a840152505061428e61428061427a614268603b850189613bca565b650b080c0b8c0b60d21b815260060190565b86613bca565b615d7d60f01b815260020190565b9998505050505050505050565b6000673d9136b2b9b4111d60c11b80835289516142bf816008860160208e01613787565b702c227472616e736c6174696f6e223a205b60781b60089185019182015289516142f0816019840160208e01613787565b650b080c0b8c0b60d21b60199290910191820152885161431781601f840160208d01613787565b80820191505062175f4b60ea1b601f8201528160228201528751915061434482602a830160208b01613787565b61439461427a61438561437f614268614379602a88880101702c227472616e736c6174696f6e223a205b60781b815260110190565b8c613bca565b89613bca565b62175f4b60ea1b815260030190565b9b9a5050505050505050505050565b60008160001904831182151516156143bd576143bd613b77565b500290565b6000826143d1576143d1613cea565b500490565b600181815b808511156144115781600019048211156143f7576143f7613b77565b8085161561440457918102915b93841c93908002906143db565b509250929050565b60008261442857506001610517565b8161443557506000610517565b816001811461444b576002811461445557614471565b6001915050610517565b60ff84111561446657614466613b77565b50506001821b610517565b5060208310610133831016604e8410600b8410161715614494575081810a610517565b61449e83836143d6565b80600019048211156144b2576144b2613b77565b029392505050565b600061224760ff841683614419565b6000826144d8576144d8613cea565b500690565b60006001600160a01b0380871683528086166020840152508360408301526080606083015261450f60808301846137b3565b9695505050505050565b60006020828403121561452b57600080fd5b81516122478161375456fe2262756666657273223a205b7b22627974654c656e677468223a203634382c22757269223a2022646174613a6170706c69636174696f6e2f6f637465742d73747265616d3b6261736536342c4141414176774141414c38414141412f4141414150774141414c38414141412f4141414176774141414438414141412f4141414150774141414438414141412f4141414150774141414c38414141412f4141414176774141414c38414141412f4141414150774141414c38414141432f4141414176774141414c38414141432f4141414150774141414438414141412f4141414150774141414c38414141412f4141414150774141414438414141432f4141414150774141414c38414141432f4141414176774141414438414141412f4141414150774141414438414141412f4141414176774141414438414141432f4141414150774141414438414141432f4141414176774141414c38414141412f4141414176774141414438414141412f4141414176774141414c38414141432f4141414176774141414438414141432f4141414176774141414c38414141432f4141414176774141414438414141432f4141414150774141414c38414141432f4141414150774141414438414141432f4141444176674141774c3441414d412b4141444150674141774c3441414d412b414144417667414177443441414d412b414144415067414177443441414d412b4141444150674141774c3441414d412b4141444176674141774c3441414d412b4141444150674141774c3441414d432b4141444176674141774c3441414d432b414144415067414177443441414d412b4141444150674141774c3441414d412b414144415067414177443441414d432b4141444150674141774c3441414d432b414144417667414177443441414d412b414144415067414177443441414d412b414144417667414177443441414d432b414144415067414177443441414d432b4141444176674141774c3441414d412b414144417667414177443441414d412b4141444176674141774c3441414d432b414144417667414177443441414d432b4141444176674141774c3441414d432b414144417667414177443441414d432b4141444150674141774c3441414d432b414144415067414177443441414d432b7b227072696d697469766573223a205b7b2261747472696275746573223a207b22504f534954494f4e223a20302c20224e4f524d414c223a20317d2c22696e6469636573223a20322c226d6174657269616c223a207b226275666665725669657722203a20302c22636f6d706f6e656e745479706522203a20353132362c22636f756e7422203a2032342c226d617822203a205b302e352c302e352c302e355d2c226d696e22203a205b2d302e352c2d302e352c2d302e355d2c227479706522203a202256454333227d2c4141414141414141414141414149412f4141414141414141414141414149412f4141414141414141414141414149412f4141414141414141414141414149412f4141414141414141674c3841414143414141414141414141674c3841414143414141414141414141674c3841414143414141414141414141674c3841414143414141434150774141414141414141434141414341507741414141414141414341414143415077414141414141414143414141434150774141414141414141434141414141414141416744384141414341414141414141414167443841414143414141414141414141674438414141434141414141414141416744384141414341414143417677414141414141414143414141434176774141414141414141434141414341767741414141414141414341414143417677414141414141414143414141414141414141414141414149432f4141414141414141414141414149432f4141414141414141414141414149432f4141414141414141414141414149432f41414142414149414177414341414541424141464141594142774147414155414341414a41416f414377414b41416b414441414e414134414477414f414130414541415241424941457741534142454146414156414259414677415741425541227d5d4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222076657273696f6e3d22312e31222076696577426f783d22302030203332203332223e3c66696c7465722069643d226931222077696474683d223135302522206865696768743d2231353025223e3c66654f666673657420726573756c743d226f66664f75742220696e3d22536f7572636547726170686963222064783d2231222064793d2230222f3e3c66654f666673657420726573756c743d226f6666324f75742220696e3d22536f7572636547726170686963222064783d222d31222064793d2230222f3e3c6665436f6c6f724d617472697820726573756c743d226d61747269784f75742220696e3d226f66664f75742220747970653d226d6174726978222076616c7565733d22302030203020302030203020312030203020302030203020312030203020302030203020302e342030222f3e3c6665436f6c6f724d617472697820726573756c743d226d6174726978324f75742220696e3d226f6666324f75742220747970653d226d6174726978222076616c7565733d22312030203020302030203020302030203020302030203020302030203020302030203020302e342030222f3e3c6665426c656e6420726573756c743d22626c656e64312220696e3d226d6174726978324f75742220696e323d22536f757263654772617068696322206d6f64653d226e6f726d616c222f3e3c6665426c656e6420696e3d226d61747269784f75742220696e323d22626c656e643122206d6f64653d226e6f726d616c222f3e3c2f66696c7465723e3c672066696c7465723d2275726c2823693129223e3c696d6167652077696474683d223130302522206865696768743d22313030252220687265663d22646174613a696d6167652f7376672b786d6c3b6261736536342c7b226173736574223a207b2267656e657261746f72223a2022426c6974626c6f782e736f6c222c2276657273696f6e223a2022322e30227d2c227363656e65223a20302c227363656e6573223a205b7b226e6f646573223a205b305d7d5d2c7b2262756666657222203a20302c22627974654c656e67746822203a2037322c22627974654f666673657422203a203537367d7b226275666665725669657722203a20322c22636f6d706f6e656e745479706522203a20353132332c22636f756e7422203a2033362c227479706522203a20225343414c4152227d226e6f646573223a205b7b226368696c6472656e223a205b312c322c332c342c352c362c372c382c392c31302c31312c31322c31332c31342c31352c31362c31372c31382c31392c32302c32312c32322c32332c32342c32352c32362c32372c32382c32392c33302c33312c33322c33332c33342c33352c33362c33372c33382c33392c34302c34312c34322c34332c34342c34352c34362c34372c34382c34392c35302c35312c35322c35332c35342c35352c35362c35372c35382c35392c36302c36312c36322c36332c36342c36352c36362c36372c36382c36392c37302c37312c37322c37332c37342c37352c37362c37372c37382c37392c38302c38312c38322c38332c38342c38352c38362c38372c38382c38392c39302c39312c39322c39332c39342c39352c39362c39372c39382c39392c3130302c3130312c3130322c3130332c3130342c3130352c3130362c3130372c3130382c3130392c3131302c3131312c3131322c3131332c3131342c3131352c3131362c3131372c3131382c3131392c3132302c3132312c3132322c3132332c3132342c3132352c3132362c3132372c3132382c3132392c3133302c3133312c3133322c3133332c3133342c3133352c3133362c3133372c3133382c3133392c3134302c3134312c3134322c3134332c3134342c3134352c3134362c3134372c3134382c3134392c3135302c3135312c3135322c3135332c3135342c3135352c3135362c3135372c3135382c3135392c3136302c3136312c3136322c3136332c3136342c3136352c3136362c3136372c3136382c3136392c3137302c3137312c3137322c3137332c3137342c3137352c3137362c3137372c3137382c3137392c3138302c3138312c3138322c3138332c3138342c3138352c3138362c3138372c3138382c3138392c3139302c3139312c3139322c3139332c3139342c3139352c3139362c3139372c3139382c3139392c3230302c3230312c3230322c3230332c3230342c3230352c3230362c3230372c3230382c3230392c3231302c3231312c3231322c3231332c3231342c3231352c3231362c3231372c3231382c3231392c3232302c3232312c3232322c3232332c3232342c3232352c3232362c3232372c3232382c3232392c3233302c3233312c3233322c3233332c3233342c3233352c3233362c3233372c3233382c3233392c3234302c3234312c3234322c3234332c3234342c3234352c3234362c3234372c3234382c3234392c3235302c3235312c3235322c3235332c3235342c3235352c3235362c3235372c3235382c3235392c3236302c3236312c3236322c3236332c3236342c3236352c3236362c3236372c3236382c3236392c3237302c3237312c3237322c3237332c3237342c3237352c3237362c3237372c3237382c3237392c3238302c3238312c3238322c3238332c3238342c3238352c3238362c3238372c3238382c3238392c3239302c3239312c3239322c3239332c3239342c3239352c3239362c3239372c3239382c3239392c3330302c3330312c3330322c3330332c3330342c3330352c3330362c3330372c3330382c3330392c3331302c3331312c3331322c3331332c3331342c3331352c3331362c3331372c3331382c3331392c3332302c3332312c3332322c3332332c3332342c3332352c3332362c3332372c3332382c3332392c3333302c3333312c3333322c3333332c3333342c3333352c3333362c3333372c3333382c3333392c3334302c3334312c3334322c3334332c3334342c3334352c3334362c3334372c3334382c3334392c3335302c3335312c3335322c3335332c3335342c3335352c3335362c3335372c3335382c3335392c3336302c3336312c3336322c3336332c3336342c3336352c3336362c3336372c3336382c3336392c3337302c3337312c3337322c3337332c3337342c3337352c3337362c3337372c3337382c3337392c3338302c3338312c3338322c3338332c3338342c3338352c3338362c3338372c3338382c3338392c3339302c3339312c3339322c3339332c3339342c3339352c3339362c3339372c3339382c3339392c3430302c3430312c3430322c3430332c3430342c3430352c3430362c3430372c3430382c3430392c3431302c3431312c3431322c3431332c3431342c3431352c3431362c3431372c3431382c3431392c3432302c3432312c3432322c3432332c3432342c3432352c3432362c3432372c3432382c3432392c3433302c3433312c3433322c3433332c3433342c3433352c3433362c3433372c3433382c3433392c3434302c3434312c3434322c3434332c3434342c3434352c3434362c3434372c3434382c3434392c3435302c3435312c3435322c3435332c3435342c3435352c3435362c3435372c3435382c3435392c3436302c3436312c3436322c3436332c3436342c3436352c3436362c3436372c3436382c3436392c3437302c3437312c3437322c3437332c3437342c3437352c3437362c3437372c3437382c3437392c3438302c3438312c3438322c3438332c3438342c3438352c3438362c3438372c3438382c3438392c3439302c3439312c3439322c3439332c3439342c3439352c3439362c3439372c3439382c3439392c3530302c3530312c3530322c3530332c3530342c3530352c3530362c3530372c3530382c3530392c3531302c3531312c3531322c3531332c3531342c3531352c3531362c3531372c3531382c3531392c3532302c3532312c3532322c3532332c3532342c3532352c3532362c3532372c3532382c3532392c3533302c3533312c3533322c3533332c3533342c3533352c3533362c3533372c3533382c3533392c3534302c3534312c3534322c3534332c3534342c3534352c3534362c3534372c3534382c3534392c3535302c3535312c3535322c3535332c3535342c3535352c3535362c3535372c3535382c3535392c3536302c3536312c3536322c3536332c3536342c3536352c3536362c3536372c3536382c3536392c3537302c3537312c3537322c3537332c3537342c3537352c3537362c3537372c3537382c3537392c3538302c3538312c3538322c3538332c3538342c3538352c3538362c3538372c3538382c3538392c3539302c3539312c3539322c3539332c3539342c3539352c3539362c3539372c3539382c3539392c3630302c3630312c3630322c3630332c3630342c3630352c3630362c3630372c3630382c3630392c3631302c3631312c3631322c3631332c3631342c3631352c3631362c3631372c3631382c3631392c3632302c3632312c3632322c3632332c3632342c3632352c3632362c3632372c3632382c3632392c3633302c3633312c3633322c3633332c3633342c3633352c3633362c3633372c3633382c3633392c3634302c3634312c3634322c3634332c3634342c3634352c3634362c3634372c3634382c3634392c3635302c3635312c3635322c3635332c3635342c3635352c3635362c3635372c3635382c3635392c3636302c3636312c3636322c3636332c3636342c3636352c3636362c3636372c3636382c3636392c3637302c3637312c3637322c3637332c3637342c3637352c3637362c3637372c3637382c3637392c3638302c3638312c3638322c3638332c3638342c3638352c3638362c3638372c3638382c3638392c3639302c3639312c3639322c3639332c3639342c3639352c3639362c3639372c3639382c3639392c3730302c3730312c3730322c3730332c3730342c3730352c3730362c3730372c3730382c3730392c3731302c3731312c3731322c3731332c3731342c3731352c3731362c3731372c3731382c3731392c3732302c3732312c3732322c3732332c3732342c3732352c3732362c3732372c3732382c3732392c3733302c3733312c3733322c3733332c3733342c3733352c3733362c3733372c3733382c3733392c3734302c3734312c3734322c3734332c3734342c3734352c3734362c3734372c3734382c3734392c3735302c3735312c3735322c3735332c3735342c3735352c3735362c3735372c3735382c3735392c3736302c3736312c3736322c3736332c3736342c3736352c3736362c3736372c3736382c3736392c3737302c3737312c3737322c3737332c3737342c3737352c3737362c3737372c3737382c3737392c3738302c3738312c3738322c3738332c3738342c3738352c3738362c3738372c3738382c3738392c3739302c3739312c3739322c3739332c3739342c3739352c3739362c3739372c3739382c3739392c3830302c3830312c3830322c3830332c3830342c3830352c3830362c3830372c3830382c3830392c3831302c3831312c3831322c3831332c3831342c3831352c3831362c3831372c3831382c3831392c3832302c3832312c3832322c3832332c3832342c3832352c3832362c3832372c3832382c3832392c3833302c3833312c3833322c3833332c3833342c3833352c3833362c3833372c3833382c3833392c3834302c3834312c3834322c3834332c3834342c3834352c3834362c3834372c3834382c3834392c3835302c3835312c3835322c3835332c3835342c3835352c3835362c3835372c3835382c3835392c3836302c3836312c3836322c3836332c3836342c3836352c3836362c3836372c3836382c3836392c3837302c3837312c3837322c3837332c3837342c3837352c3837362c3837372c3837382c3837392c3838302c3838312c3838322c3838332c3838342c3838352c3838362c3838372c3838382c3838392c3839302c3839312c3839322c3839332c3839342c3839352c3839362c3839372c3839382c3839392c3930302c3930312c3930322c3930332c3930342c3930352c3930362c3930372c3930382c3930392c3931302c3931312c3931322c3931332c3931342c3931352c3931362c3931372c3931382c3931392c3932302c3932312c3932322c3932332c3932342c3932352c3932362c3932372c3932382c3932392c3933302c3933312c3933322c3933332c3933342c3933352c3933362c3933372c3933382c3933392c3934302c3934312c3934322c3934332c3934342c3934352c3934362c3934372c3934382c3934392c3935302c3935312c3935322c3935332c3935342c3935352c3935362c3935372c3935382c3935392c3936302c3936312c3936322c3936332c3936342c3936352c3936362c3936372c3936382c3936392c3937302c3937312c3937322c3937332c3937342c3937352c3937362c3937372c3937382c3937392c3938302c3938312c3938322c3938332c3938342c3938352c3938362c3938372c3938382c3938392c3939302c3939312c3939322c3939332c3939342c3939352c3939362c3939372c3939382c3939392c313030302c313030312c313030322c313030332c313030342c313030352c313030362c313030372c313030382c313030392c313031302c313031312c313031322c313031332c313031342c313031352c313031362c313031372c313031382c313031392c313032302c313032312c313032322c313032332c313032345d2c7b226275666665725669657722203a20312c22636f6d706f6e656e745479706522203a20353132362c22636f756e7422203a2032342c227479706522203a202256454333227d2c7b2262756666657222203a20302c22627974654c656e67746822203a203238382c22627974654f666673657422203a20307d2c7b227062724d6574616c6c6963526f7567686e657373223a207b2262617365436f6c6f72466163746f72223a205b7b2262756666657222203a20302c22627974654c656e67746822203a203238382c22627974654f666673657422203a203238387d2c226d6174726978223a205b312e302c302e302c302e302c302e302c302e302c302e302c312e302c302e302c302e302c312e302c302e302c302e302c302e302c302e302c302e302c312e305d7d2ca164736f6c6343000809000a0000000000000000000000008d04a8c79ceb0889bdd12acdf3fa9d207ed3ff630000000000000000000000000e4b8e24789630618aa90072f520711d3d9db647

Deployed Bytecode

0x6080604052600436106101805760003560e01c80638da5cb5b116100d6578063c87b56dd1161007f578063e985e9c511610059578063e985e9c51461042a578063efd4606514610473578063f2fde38b146104ab57600080fd5b8063c87b56dd146103d7578063d0b23ba4146103f7578063e0e0daea1461041757600080fd5b8063a22cb465116100b0578063a22cb46514610382578063b1111359146103a2578063b88d4fde146103b757600080fd5b80638da5cb5b146103195780638e13a1461461033757806395d89b411461036d57600080fd5b80632fde60a0116101385780636352211e116101125780636352211e146102b657806370a08231146102d6578063715018a61461030457600080fd5b80632fde60a01461025657806342842e0e146102765780635b9a19d01461029657600080fd5b8063081812fc11610169578063081812fc146101dc578063095ea7b31461021457806323b872dd1461023657600080fd5b806301ffc9a71461018557806306fdde03146101ba575b600080fd5b34801561019157600080fd5b506101a56101a036600461376a565b6104cb565b60405190151581526020015b60405180910390f35b3480156101c657600080fd5b506101cf61051d565b6040516101b191906137df565b3480156101e857600080fd5b506101fc6101f73660046137f2565b6105af565b6040516001600160a01b0390911681526020016101b1565b34801561022057600080fd5b5061023461022f366004613820565b610649565b005b34801561024257600080fd5b5061023461025136600461384c565b61075f565b34801561026257600080fd5b5061023461027136600461393a565b6107e6565b34801561028257600080fd5b5061023461029136600461384c565b610857565b3480156102a257600080fd5b506101cf6102b13660046139c0565b610872565b3480156102c257600080fd5b506101fc6102d13660046137f2565b611b7a565b3480156102e257600080fd5b506102f66102f1366004613a0e565b611c05565b6040519081526020016101b1565b34801561031057600080fd5b50610234611c9f565b34801561032557600080fd5b506006546001600160a01b03166101fc565b34801561034357600080fd5b506102f6610352366004613a0e565b6001600160a01b03166000908152600b602052604090205490565b34801561037957600080fd5b506101cf611d05565b34801561038e57600080fd5b5061023461039d366004613a2b565b611d14565b3480156103ae57600080fd5b50610234611dd9565b3480156103c357600080fd5b506102346103d2366004613a69565b611e94565b3480156103e357600080fd5b506101cf6103f23660046137f2565b611f22565b34801561040357600080fd5b506101cf6104123660046137f2565b612113565b610234610425366004613ad5565b61224e565b34801561043657600080fd5b506101a5610445366004613af8565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561047f57600080fd5b506101a561048e366004613a0e565b6001600160a01b03166000908152600b6020526040902054151590565b3480156104b757600080fd5b506102346104c6366004613a0e565b612818565b60006001600160e01b031982166380ac58cd60e01b14806104fc57506001600160e01b03198216635b5e139f60e01b145b8061051757506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461052c90613b26565b80601f016020809104026020016040519081016040528092919081815260200182805461055890613b26565b80156105a55780601f1061057a576101008083540402835291602001916105a5565b820191906000526020600020905b81548152906001019060200180831161058857829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661062d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061065482611b7a565b9050806001600160a01b0316836001600160a01b031614156106c25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610624565b336001600160a01b03821614806106de57506106de8133610445565b6107505760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610624565b61075a83836128fa565b505050565b6107693382612968565b6107db5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610624565b61075a838383612a5f565b6006546001600160a01b031633146108405760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610624565b8051610853906009906020840190613693565b5050565b61075a83838360405180602001604052806000815250611e94565b606060008060fc84901c600f60f886901c16604080516104408101825260016104008201818152600360fc1b610420840152825282518084018452818152603160f81b6020828101919091528084019190915283518085018552828152601960f91b818301528385015283518085018552828152603360f81b8183015260608085019190915284518086018652838152600d60fa1b8184015260808086019190915285518087018752848152603560f81b8185015260a08087019190915286518088018852858152601b60f91b8186015260c08088019190915287518089018952868152603760f81b8187015260e088015287518089018952868152600760fb1b8187015261010088015287518089018952958652603960f81b8686015261012087019590955286518088018852600280825261031360f41b828701526101408801919091528751808901895281815261313160f01b818701526101608801528751808901895281815261189960f11b818701526101808801528751808901895281815261313360f01b818701526101a088015287518089018952818152610c4d60f21b818701526101c08801528751808901895281815261313560f01b818701526101e08801528751808901895281815261189b60f11b818701526102008801528751808901895281815261313760f01b818701526102208801528751808901895281815261062760f31b818701526102408801528751808901895281815261313960f01b818701526102608801528751808901895281815261032360f41b818701526102808801528751808901895281815261323160f01b818701526102a08801528751808901895281815261191960f11b818701526102c08801528751808901895281815261323360f01b818701526102e088015287518089018952818152610c8d60f21b818701526103008801528751808901895281815261323560f01b818701526103208801528751808901895281815261191b60f11b818701526103408801528751808901895281815261323760f01b818701526103608801528751808901895281815261064760f31b818701526103808801528751808901895281815261323960f01b818701526103a08801528751808901895281815261033360f41b818701526103c08801528751808901895290815261333160f01b818601526103e0870152865194850187526000808652938501849052958401839052908301829052820181905292810192909252929450909250600060405180608001604052806040518060600160405280610c438c600081518110610c3857610c38613b61565b016020015160f81c90565b8152602001610c5e8c600181518110610c3857610c38613b61565b8152602001610c798c600281518110610c3857610c38613b61565b81525081526020016040518060600160405280610ca28c600381518110610c3857610c38613b61565b8152602001610cbd8c600481518110610c3857610c38613b61565b8152602001610cd88c600581518110610c3857610c38613b61565b81525081526020016040518060600160405280610d018c600681518110610c3857610c38613b61565b8152602001610d1c8c600781518110610c3857610c38613b61565b8152602001610d378c600881518110610c3857610c38613b61565b81525081526020016040518060600160405280610d608c600981518110610c3857610c38613b61565b8152602001610d7b8c600a81518110610c3857610c38613b61565b8152602001610d968c600b81518110610c3857610c38613b61565b905290529050610da4613717565b60006040518060800160405280605f8152602001614e22605f91399050610de681604051806110000160405280610fc68152602001614efc610fc69139612c13565b9050610e0a816040518060800160405280604d8152602001615f9f604d9139612c13565b9050600c5b61010c8110156113cd57610e468b8281518110610e2e57610e2e613b61565b01602001516001600160f81b03191660066007612c3f565b60408601528a51610e7b908c9083908110610e6357610e63613b61565b01602001516001600160f81b03191660046005612c3f565b60608601528a51610eb0908c9083908110610e9857610e98613b61565b01602001516001600160f81b03191660026003612c3f565b60808601528a51610ee5908c9083908110610ecd57610ecd613b61565b01602001516001600160f81b03191660006001612c3f565b60a0860152610ef48686612ce6565b8352610f218360005b6020020151604051806040016040528060018152602001600b60fa1b815250612c13565b835284516004908690610f35908390613b8d565b60ff16905250610f5a8b610f4a836001613bb2565b81518110610e2e57610e2e613b61565b6040860152610f7e8b610f6e836001613bb2565b81518110610e6357610e63613b61565b6060860152610fa28b610f92836001613bb2565b81518110610e9857610e98613b61565b6080860152610fc68b610fb6836001613bb2565b81518110610ecd57610ecd613b61565b60a0860152610fd58686612ce6565b6020840152610fe5836001610efd565b602084015284516004908690610ffc908390613b8d565b60ff169052506110118b610f4a836002613bb2565b60408601526110258b610f6e836002613bb2565b60608601526110398b610f92836002613bb2565b608086015261104d8b610fb6836002613bb2565b60a086015261105c8686612ce6565b604084015261106c836002610efd565b604084015284516004908690611083908390613b8d565b60ff169052506110988b610f4a836003613bb2565b60408601526110ac8b610f6e836003613bb2565b60608601526110c08b610f92836003613bb2565b60808601526110d48b610fb6836003613bb2565b60a08601526110e38686612ce6565b60608401526110f3836003610efd565b60608401528451600490869061110a908390613b8d565b60ff1690525061111f8b610f4a836004613bb2565b60408601526111338b610f6e836004613bb2565b60608601526111478b610f92836004613bb2565b608086015261115b8b610fb6836004613bb2565b60a086015261116a8686612ce6565b608084015261117a836004610efd565b608084015284516004908690611191908390613b8d565b60ff169052506111a68b610f4a836005613bb2565b60408601526111ba8b610f6e836005613bb2565b60608601526111ce8b610f92836005613bb2565b60808601526111e28b610fb6836005613bb2565b60a08601526111f18686612ce6565b60a0840152611201836005610efd565b60a084015284516004908690611218908390613b8d565b60ff1690525061122d8b610f4a836006613bb2565b60408601526112418b610f6e836006613bb2565b60608601526112558b610f92836006613bb2565b60808601526112698b610fb6836006613bb2565b60a08601526112788686612ce6565b60c0840152611288836006610efd565b60c08401528451600490869061129f908390613b8d565b60ff169052506112b48b610f4a836007613bb2565b60408601526112c88b610f6e836007613bb2565b60608601526112dc8b610f92836007613bb2565b60808601526112f08b610fb6836007613bb2565b60a08601526112ff8686612ce6565b60e084015261010c611312826009613bb2565b101561132957611323836007610efd565b60e08401525b60048560000181815161133c9190613b8d565b60ff1690525082516020808501516040808701516060880151608089015160a08a015160c08b015160e08c0151955161137b998c999098979101613be6565b60405160208183030381529060405291506020856000015160ff16106113bb5760008552602085018051600191906113b4908390613b8d565b60ff169052505b6113c6600882613bb2565b9050610e0f565b506113f28160405180604001604052806002815260200161174b60f21b815250612c13565b9050611433816040518060400160405280600e81526020017f226d6174657269616c73223a205b000000000000000000000000000000000000815250612c13565b905060005b600481101561176457611463826040518060600160405280602e8152602001615f3c602e9139612c13565b91508161148d85836004811061147b5761147b613b61565b602002015160005b6020020151612e8d565b604051806040016040528060018152602001600b60fa1b8152506040516020016114b993929190613ca7565b6040516020818303038152906040529150816114ec8583600481106114e0576114e0613b61565b60200201516001611483565b604051806040016040528060018152602001600b60fa1b81525060405160200161151893929190613ca7565b60405160208183030381529060405291508161154b85836004811061153f5761153f613b61565b60200201516002611483565b604051806040016040528060018152602001600b60fa1b81525060405160200161157793929190613ca7565b60408051601f198184030181529190529150611594600289613d00565b60ff1660011480156115a857508660ff1681145b156115f1578160405180604001604052806003815260200162302e3560e81b8152506040516020016115db929190613d22565b6040516020818303038152906040529150611631565b81604051806040016040528060038152602001620312e360ec1b81525060405160200161161f929190613d22565b60405160208183030381529060405291505b611670826040518060400160405280601981526020017f5d2c226d6574616c6c6963466163746f72223a20302e307d2c00000000000000815250612c13565b915061167d600289613d00565b60ff16600114801561169157508660ff1681145b156116d8576116d5826040518060400160405280601581526020017f22616c7068614d6f6465223a2022424c454e44222c0000000000000000000000815250612c13565b91505b611717826040518060400160405280601381526020017f226e616d65223a20226d6174657269616c227d00000000000000000000000000815250612c13565b91506004611726826001613bb2565b10156117525761174f82604051806040016040528060018152602001600b60fa1b815250612c13565b91505b8061175c81613d51565b915050611438565b506117898160405180604001604052806002815260200161174b60f21b815250612c13565b90506117ca816040518060400160405280600b81526020017f226d6573686573223a205b000000000000000000000000000000000000000000815250612c13565b905060005b60048110156118d1576117fa8260405180608001604052806055815260200161488360559139612c13565b915061180e8261180983613015565b612c13565b915061184f826040518060400160405280601081526020017f7d5d2c226e616d65223a20224d65736800000000000000000000000000000000815250612c13565b915061185e8261180983613015565b91506118848260405180604001604052806002815260200161227d60f01b815250612c13565b91506004611893826001613bb2565b10156118bf576118bc82604051806040016040528060018152602001600b60fa1b815250612c13565b91505b806118c981613d51565b9150506117cf565b506118f68160405180604001604052806002815260200161174b60f21b815250612c13565b9050611937816040518060400160405280600e81526020017f226163636573736f7273223a205b000000000000000000000000000000000000815250612c13565b905061195b816040518060a00160405280607681526020016148d860769139612c13565b905061197f81604051806080016040528060478152602001615ec260479139612c13565b90506119a381604051806080016040528060488152602001614eb460489139612c13565b90506119c98160405180604001604052806002815260200161174b60f21b815250612c13565b9050611a0a816040518060400160405280601081526020017f226275666665725669657773223a205b00000000000000000000000000000000815250612c13565b9050611a2e81604051806060016040528060338152602001615f0960339139612c13565b9050611a5281604051806060016040528060358152602001615f6a60359139612c13565b9050611a7681604051806060016040528060338152602001614e8160339139612c13565b9050611a9c8160405180604001604052806002815260200161174b60f21b815250612c13565b9050611ac0816040518060800160405280604c8152602001614537604c9139612c13565b905060028760ff161015611afa57611af381604051806101a0016040528061018081526020016145836101809139612c13565b9050611b22565b611b1f81604051806101a0016040528061018081526020016147036101809139612c13565b90505b611b47816040518061022001604052806101e3815260200161494e6101e39139612c13565b9050611b6c81604051806040016040528060018152602001607d60f81b815250612c13565b9a9950505050505050505050565b6000818152600260205260408120546001600160a01b0316806105175760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610624565b60006001600160a01b038216611c835760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610624565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b03163314611cf95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610624565b611d03600061312b565b565b60606001805461052c90613b26565b6001600160a01b038216331415611d6d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610624565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60026007541415611e2c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610624565b6002600755336000908152600b6020526040902054611e4a57600080fd5b336000818152600b6020526040808220805490839055905190929183156108fc02918491818181858888f19350505050158015611e8b573d6000803e3d6000fd5b50506001600755565b611e9e3383612968565b611f105760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610624565b611f1c8484848461317d565b50505050565b60606000604051806102e001604052806102b18152602001614b716102b1913990506106a483101561200157600d5460405163a78d070f60e01b8152600481018590528291611fda916001600160a01b039091169063a78d070f906024015b60006040518083038186803b158015611f9957600080fd5b505afa158015611fad573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611fd59190810190613d9c565b6131fb565b604051602001611feb929190613d22565b604051602081830303815290604052905061205b565b600c5460405163a78d070f60e01b8152600481018590528291612038916001600160a01b039091169063a78d070f90602401611f81565b604051602001612049929190613d22565b60405160208183030381529060405290505b8060405160200161206c9190613de5565b6040516020818303038152906040529050612086816131fb565b6040516020016120969190613e26565b604051602081830303815290604052905060006120e86120b585613015565b8360096120c188613015565b6040516020016120d49493929190613f05565b6040516020818303038152906040526131fb565b9050806040516020016120fb91906140da565b60405160208183030381529060405292505050919050565b6060806106a48310156121a757600d5460405163c0da9bcd60e01b8152600481018590526001600160a01b039091169063c0da9bcd9060240160006040518083038186803b15801561216457600080fd5b505afa158015612178573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526121a09190810190613d9c565b905061222a565b600c5460405163c0da9bcd60e01b8152600481018590526001600160a01b039091169063c0da9bcd9060240160006040518083038186803b1580156121eb57600080fd5b505afa1580156121ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122279190810190613d9c565b90505b6000838152600a602052604090205461224790829060f81b610872565b9392505050565b600260075414156122a15760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610624565b600260075560085434146122b457600080fd5b6106a482101561235257600d546040516331a9108f60e11b81526004810184905233916001600160a01b031690636352211e9060240160206040518083038186803b15801561230257600080fd5b505afa158015612316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233a919061411f565b6001600160a01b03161461234d57600080fd5b6123e1565b600c546040516331a9108f60e11b81526004810184905233916001600160a01b031690636352211e9060240160206040518083038186803b15801561239657600080fd5b505afa1580156123aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ce919061411f565b6001600160a01b0316146123e157600080fd5b60006123f56006546001600160a01b031690565b9050600061240b6006546001600160a01b031690565b9050606484101561251257600d546040516306daaebd60e01b8152600481018690526001600160a01b03909116906306daaebd9060240160206040518083038186803b15801561245a57600080fd5b505afa15801561246e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612492919061411f565b600d546040516306daaebd60e01b8152600481018790529193506001600160a01b0316906306daaebd9060240160206040518083038186803b1580156124d757600080fd5b505afa1580156124eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250f919061411f565b90505b606384111561272c576000806106a48610156125ad57600d54604051630d3488e560e41b8152600481018890526001600160a01b039091169063d3488e5090602401604080518083038186803b15801561256b57600080fd5b505afa15801561257f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a3919061413c565b909250905061262e565b600c54604051630d3488e560e41b8152600481018890526001600160a01b039091169063d3488e5090602401604080518083038186803b1580156125f057600080fd5b505afa158015612604573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612628919061413c565b90925090505b600d546040516306daaebd60e01b8152600481018490526001600160a01b03909116906306daaebd9060240160206040518083038186803b15801561267257600080fd5b505afa158015612686573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126aa919061411f565b600d546040516306daaebd60e01b8152600481018490529195506001600160a01b0316906306daaebd9060240160206040518083038186803b1580156126ef57600080fd5b505afa158015612703573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612727919061411f565b925050505b6000848152600a60205260409020805460ff191660f885901c1790556127523385613361565b6001600160a01b0382166000908152600b602052604081208054660d529ae9e860009290612781908490613bb2565b90915550506001600160a01b0381166000908152600b602052604081208054660470de4df8200092906127b5908490613bb2565b9091555066354a6ba7a180009050600b60006127d96006546001600160a01b031690565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008282546128089190613bb2565b9091555050600160075550505050565b6006546001600160a01b031633146128725760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610624565b6001600160a01b0381166128ee5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610624565b6128f78161312b565b50565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061292f82611b7a565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166129e15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610624565b60006129ec83611b7a565b9050806001600160a01b0316846001600160a01b03161480612a275750836001600160a01b0316612a1c846105af565b6001600160a01b0316145b80612a5757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316612a7282611b7a565b6001600160a01b031614612aee5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610624565b6001600160a01b038216612b505760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610624565b612b5b6000826128fa565b6001600160a01b0383166000908152600360205260408120805460019290612b84908490614160565b90915550506001600160a01b0382166000908152600360205260408120805460019290612bb2908490613bb2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60608282604051602001612c28929190613d22565b604051602081830303815290604052905092915050565b6000600160f885901c60ff84161c8116148015612c675750600160f885901c60ff85161c8116145b15612c7457506003612247565b600160f885901c60ff84161c8116148015612c9b5750600160f885901c60ff85161c811614155b15612ca857506002612247565b600160f885901c60ff84161c811614158015612ccf5750600160f885901c60ff85161c8116145b15612cdc57506001612247565b5060009392505050565b6060612cf58260400151613015565b8251849060ff1660208110612d0c57612d0c613b61565b6020020151848460200151601f612d239190614177565b60ff1660208110612d3657612d36613b61565b6020020151612d488560600151613015565b85518790612d57906001613b8d565b60ff1660208110612d6a57612d6a613b61565b6020020151878760200151601f612d819190614177565b60ff1660208110612d9457612d94613b61565b6020020151612da68860800151613015565b88518a90612db5906002613b8d565b60ff1660208110612dc857612dc8613b61565b60200201518a8a60200151601f612ddf9190614177565b60ff1660208110612df257612df2613b61565b6020020151612e048b60a00151613015565b8b518d90612e13906003613b8d565b60ff1660208110612e2657612e26613b61565b60200201518d8d60200151601f612e3d9190614177565b60ff1660208110612e5057612e50613b61565b6020020151604051602001612e6a9695949392919061419a565b60408051601f1981840301815290829052612c289796959493929160200161429b565b60606000612e9e6103e860ff6143a3565b612eaa6103e8806143a3565b612eb66103e8866143a3565b612ec091906143a3565b612eca91906143c2565b9050612ed86103e8806143a3565b612ee36002836144ba565b612eed91906143c2565b90506000612f0f612f006103e8806143a3565b612f0a90846143c2565b613015565b604051806040016040528060018152602001601760f91b815250604051602001612f3a929190613d22565b60408051601f19818403018152919052905080612f74620186a0612f606103e8806143a3565b612f6a90866144c9565b612f0a91906143c2565b604051602001612f85929190613d22565b60408051601f19818403018152919052905080612fb6612710600a612fac6103e8806143a3565b612f6091906143c2565b604051602001612fc7929190613d22565b60408051601f19818403018152919052905080612fec6103e86064612fac82806143a3565b604051602001612ffd929190613d22565b60408051601f19818403018152919052949350505050565b6060816130395750506040805180820190915260018152600360fc1b602082015290565b8160005b8115613063578061304d81613d51565b915061305c9050600a836143c2565b915061303d565b60008167ffffffffffffffff81111561307e5761307e61388d565b6040519080825280601f01601f1916602001820160405280156130a8576020820181803683370190505b5090505b8415612a57576130bd600183614160565b91506130ca600a866144c9565b6130d5906030613bb2565b60f81b8183815181106130ea576130ea613b61565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613124600a866143c2565b94506130ac565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613188848484612a5f565b6131948484848461337b565b611f1c5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610624565b80516060908061321b575050604080516020810190915260008152919050565b6000600361322a836002613bb2565b61323491906143c2565b61323f9060046143a3565b9050600061324e826020613bb2565b67ffffffffffffffff8111156132665761326661388d565b6040519080825280601f01601f191660200182016040528015613290576020820181803683370190505b5090506000604051806060016040528060408152602001614b31604091399050600181016020830160005b8681101561331c576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016132bb565b506003860660018114613336576002811461334757613353565b613d3d60f01b600119830152613353565b603d60f81b6000198301525b505050918152949350505050565b6108538282604051806020016040528060008152506134d3565b60006001600160a01b0384163b156134c857604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906133bf9033908990889088906004016144dd565b602060405180830381600087803b1580156133d957600080fd5b505af1925050508015613409575060408051601f3d908101601f1916820190925261340691810190614519565b60015b6134ae573d808015613437576040519150601f19603f3d011682016040523d82523d6000602084013e61343c565b606091505b5080516134a65760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610624565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612a57565b506001949350505050565b6134dd8383613551565b6134ea600084848461337b565b61075a5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610624565b6001600160a01b0382166135a75760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610624565b6000818152600260205260409020546001600160a01b03161561360c5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610624565b6001600160a01b0382166000908152600360205260408120805460019290613635908490613bb2565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461369f90613b26565b90600052602060002090601f0160209004810192826136c15760008555613707565b82601f106136da57805160ff1916838001178555613707565b82800160010185558215613707579182015b828111156137075782518255916020019190600101906136ec565b5061371392915061373f565b5090565b6040518061010001604052806008905b60608152602001906001900390816137275790505090565b5b808211156137135760008155600101613740565b6001600160e01b0319811681146128f757600080fd5b60006020828403121561377c57600080fd5b813561224781613754565b60005b838110156137a257818101518382015260200161378a565b83811115611f1c5750506000910152565b600081518084526137cb816020860160208601613787565b601f01601f19169290920160200192915050565b60208152600061224760208301846137b3565b60006020828403121561380457600080fd5b5035919050565b6001600160a01b03811681146128f757600080fd5b6000806040838503121561383357600080fd5b823561383e8161380b565b946020939093013593505050565b60008060006060848603121561386157600080fd5b833561386c8161380b565b9250602084013561387c8161380b565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156138cc576138cc61388d565b604052919050565b600067ffffffffffffffff8211156138ee576138ee61388d565b50601f01601f191660200190565b600061390f61390a846138d4565b6138a3565b905082815283838301111561392357600080fd5b828260208301376000602084830101529392505050565b60006020828403121561394c57600080fd5b813567ffffffffffffffff81111561396357600080fd5b8201601f8101841361397457600080fd5b612a57848235602084016138fc565b600082601f83011261399457600080fd5b612247838335602085016138fc565b80356001600160f81b0319811681146139bb57600080fd5b919050565b600080604083850312156139d357600080fd5b823567ffffffffffffffff8111156139ea57600080fd5b6139f685828601613983565b925050613a05602084016139a3565b90509250929050565b600060208284031215613a2057600080fd5b81356122478161380b565b60008060408385031215613a3e57600080fd5b8235613a498161380b565b915060208301358015158114613a5e57600080fd5b809150509250929050565b60008060008060808587031215613a7f57600080fd5b8435613a8a8161380b565b93506020850135613a9a8161380b565b925060408501359150606085013567ffffffffffffffff811115613abd57600080fd5b613ac987828801613983565b91505092959194509250565b60008060408385031215613ae857600080fd5b82359150613a05602084016139a3565b60008060408385031215613b0b57600080fd5b8235613b168161380b565b91506020830135613a5e8161380b565b600181811c90821680613b3a57607f821691505b60208210811415613b5b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168060ff03821115613baa57613baa613b77565b019392505050565b60008219821115613bc557613bc5613b77565b500190565b60008151613bdc818560208601613787565b9290920192915050565b60008a51613bf8818460208f01613787565b8a51613c0a8183860160208f01613787565b8a519184010190613c1f818360208e01613787565b8951613c318183850160208e01613787565b8951929091010190613c47818360208c01613787565b8751613c598183850160208c01613787565b8751929091010190613c6f818360208a01613787565b8551613c818183850160208a01613787565b8551929091010190613c97818360208801613787565b019b9a5050505050505050505050565b60008451613cb9818460208901613787565b845190830190613ccd818360208901613787565b8451910190613ce0818360208801613787565b0195945050505050565b634e487b7160e01b600052601260045260246000fd5b600060ff831680613d1357613d13613cea565b8060ff84160691505092915050565b60008351613d34818460208801613787565b835190830190613d48818360208801613787565b01949350505050565b6000600019821415613d6557613d65613b77565b5060010190565b6000613d7a61390a846138d4565b9050828152838383011115613d8e57600080fd5b612247836020830184613787565b600060208284031215613dae57600080fd5b815167ffffffffffffffff811115613dc557600080fd5b8201601f81018413613dd657600080fd5b612a5784825160208401613d6c565b60008251613df7818460208701613787565b7f222f3e3c2f673e3c2f7376673e00000000000000000000000000000000000000920191825250600d01919050565b7f646174613a696d6167652f7376672b786d6c3b6261736536342c000000000000815260008251613e5e81601a850160208701613787565b91909101601a0192915050565b8054600090600181811c9080831680613e8557607f831692505b6020808410821415613ea757634e487b7160e01b600052602260045260246000fd5b818015613ebb5760018114613ecc57613ef9565b60ff19861689528489019650613ef9565b60008881526020902060005b86811015613ef15781548b820152908501908301613ed8565b505084890196505b50505050505092915050565b7f7b226e616d65223a2022426c6974626c6f782023000000000000000000000000815260008551613f3d816014850160208a01613787565b7f222c20226465736372697074696f6e223a2022426c6974626c6f7820697320616014918401918201527f20646572697661746976652070726f6a656374206f6620426c69746d6170206160348201527f6e6420466c69706d61702e2049742067656e657261746573206120746872656560548201527f2064696d656e73696f6e616c20766f78656c2076657273696f6e206f6620746860748201527f6520636f72726573706f6e64696e67206d61702e20416c6c203344206461746160948201527f2069732067656e65726174656420616e642073746f726564206f6e206368616960b48201527f6e206173206120676c54462e222c2022696d616765223a22000000000000000060d4820152855161405e8160ec840160208a01613787565b6140ce6140a561409f61409960ec858701017f222c22616e696d6174696f6e5f75726c223a2200000000000000000000000000815260130190565b89613e6b565b87613bca565b7f2e676c62227d0000000000000000000000000000000000000000000000000000815260060190565b98975050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161411281601d850160208701613787565b91909101601d0192915050565b60006020828403121561413157600080fd5b81516122478161380b565b6000806040838503121561414f57600080fd5b505080516020909101519092909150565b60008282101561417257614172613b77565b500390565b600060ff821660ff84168082101561419157614191613b77565b90039392505050565b6000673d9136b2b9b4111d60c11b80835288516141be816008860160208d01613787565b8084019050702c227472616e736c6174696f6e223a205b60781b80600883015289516141f1816019850160208e01613787565b650b080c0b8c0b60d21b60199390910192830152885161421881601f850160208d01613787565b80830192505062175f4b60ea1b601f8301528260228301528751925061424583602a840160208b01613787565b828201925080602a840152505061428e61428061427a614268603b850189613bca565b650b080c0b8c0b60d21b815260060190565b86613bca565b615d7d60f01b815260020190565b9998505050505050505050565b6000673d9136b2b9b4111d60c11b80835289516142bf816008860160208e01613787565b702c227472616e736c6174696f6e223a205b60781b60089185019182015289516142f0816019840160208e01613787565b650b080c0b8c0b60d21b60199290910191820152885161431781601f840160208d01613787565b80820191505062175f4b60ea1b601f8201528160228201528751915061434482602a830160208b01613787565b61439461427a61438561437f614268614379602a88880101702c227472616e736c6174696f6e223a205b60781b815260110190565b8c613bca565b89613bca565b62175f4b60ea1b815260030190565b9b9a5050505050505050505050565b60008160001904831182151516156143bd576143bd613b77565b500290565b6000826143d1576143d1613cea565b500490565b600181815b808511156144115781600019048211156143f7576143f7613b77565b8085161561440457918102915b93841c93908002906143db565b509250929050565b60008261442857506001610517565b8161443557506000610517565b816001811461444b576002811461445557614471565b6001915050610517565b60ff84111561446657614466613b77565b50506001821b610517565b5060208310610133831016604e8410600b8410161715614494575081810a610517565b61449e83836143d6565b80600019048211156144b2576144b2613b77565b029392505050565b600061224760ff841683614419565b6000826144d8576144d8613cea565b500690565b60006001600160a01b0380871683528086166020840152508360408301526080606083015261450f60808301846137b3565b9695505050505050565b60006020828403121561452b57600080fd5b81516122478161375456fe2262756666657273223a205b7b22627974654c656e677468223a203634382c22757269223a2022646174613a6170706c69636174696f6e2f6f637465742d73747265616d3b6261736536342c4141414176774141414c38414141412f4141414150774141414c38414141412f4141414176774141414438414141412f4141414150774141414438414141412f4141414150774141414c38414141412f4141414176774141414c38414141412f4141414150774141414c38414141432f4141414176774141414c38414141432f4141414150774141414438414141412f4141414150774141414c38414141412f4141414150774141414438414141432f4141414150774141414c38414141432f4141414176774141414438414141412f4141414150774141414438414141412f4141414176774141414438414141432f4141414150774141414438414141432f4141414176774141414c38414141412f4141414176774141414438414141412f4141414176774141414c38414141432f4141414176774141414438414141432f4141414176774141414c38414141432f4141414176774141414438414141432f4141414150774141414c38414141432f4141414150774141414438414141432f4141444176674141774c3441414d412b4141444150674141774c3441414d412b414144417667414177443441414d412b414144415067414177443441414d412b4141444150674141774c3441414d412b4141444176674141774c3441414d412b4141444150674141774c3441414d432b4141444176674141774c3441414d432b414144415067414177443441414d412b4141444150674141774c3441414d412b414144415067414177443441414d432b4141444150674141774c3441414d432b414144417667414177443441414d412b414144415067414177443441414d412b414144417667414177443441414d432b414144415067414177443441414d432b4141444176674141774c3441414d412b414144417667414177443441414d412b4141444176674141774c3441414d432b414144417667414177443441414d432b4141444176674141774c3441414d432b414144417667414177443441414d432b4141444150674141774c3441414d432b414144415067414177443441414d432b7b227072696d697469766573223a205b7b2261747472696275746573223a207b22504f534954494f4e223a20302c20224e4f524d414c223a20317d2c22696e6469636573223a20322c226d6174657269616c223a207b226275666665725669657722203a20302c22636f6d706f6e656e745479706522203a20353132362c22636f756e7422203a2032342c226d617822203a205b302e352c302e352c302e355d2c226d696e22203a205b2d302e352c2d302e352c2d302e355d2c227479706522203a202256454333227d2c4141414141414141414141414149412f4141414141414141414141414149412f4141414141414141414141414149412f4141414141414141414141414149412f4141414141414141674c3841414143414141414141414141674c3841414143414141414141414141674c3841414143414141414141414141674c3841414143414141434150774141414141414141434141414341507741414141414141414341414143415077414141414141414143414141434150774141414141414141434141414141414141416744384141414341414141414141414167443841414143414141414141414141674438414141434141414141414141416744384141414341414143417677414141414141414143414141434176774141414141414141434141414341767741414141414141414341414143417677414141414141414143414141414141414141414141414149432f4141414141414141414141414149432f4141414141414141414141414149432f4141414141414141414141414149432f41414142414149414177414341414541424141464141594142774147414155414341414a41416f414377414b41416b414441414e414134414477414f414130414541415241424941457741534142454146414156414259414677415741425541227d5d4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737667222076657273696f6e3d22312e31222076696577426f783d22302030203332203332223e3c66696c7465722069643d226931222077696474683d223135302522206865696768743d2231353025223e3c66654f666673657420726573756c743d226f66664f75742220696e3d22536f7572636547726170686963222064783d2231222064793d2230222f3e3c66654f666673657420726573756c743d226f6666324f75742220696e3d22536f7572636547726170686963222064783d222d31222064793d2230222f3e3c6665436f6c6f724d617472697820726573756c743d226d61747269784f75742220696e3d226f66664f75742220747970653d226d6174726978222076616c7565733d22302030203020302030203020312030203020302030203020312030203020302030203020302e342030222f3e3c6665436f6c6f724d617472697820726573756c743d226d6174726978324f75742220696e3d226f6666324f75742220747970653d226d6174726978222076616c7565733d22312030203020302030203020302030203020302030203020302030203020302030203020302e342030222f3e3c6665426c656e6420726573756c743d22626c656e64312220696e3d226d6174726978324f75742220696e323d22536f757263654772617068696322206d6f64653d226e6f726d616c222f3e3c6665426c656e6420696e3d226d61747269784f75742220696e323d22626c656e643122206d6f64653d226e6f726d616c222f3e3c2f66696c7465723e3c672066696c7465723d2275726c2823693129223e3c696d6167652077696474683d223130302522206865696768743d22313030252220687265663d22646174613a696d6167652f7376672b786d6c3b6261736536342c7b226173736574223a207b2267656e657261746f72223a2022426c6974626c6f782e736f6c222c2276657273696f6e223a2022322e30227d2c227363656e65223a20302c227363656e6573223a205b7b226e6f646573223a205b305d7d5d2c7b2262756666657222203a20302c22627974654c656e67746822203a2037322c22627974654f666673657422203a203537367d7b226275666665725669657722203a20322c22636f6d706f6e656e745479706522203a20353132332c22636f756e7422203a2033362c227479706522203a20225343414c4152227d226e6f646573223a205b7b226368696c6472656e223a205b312c322c332c342c352c362c372c382c392c31302c31312c31322c31332c31342c31352c31362c31372c31382c31392c32302c32312c32322c32332c32342c32352c32362c32372c32382c32392c33302c33312c33322c33332c33342c33352c33362c33372c33382c33392c34302c34312c34322c34332c34342c34352c34362c34372c34382c34392c35302c35312c35322c35332c35342c35352c35362c35372c35382c35392c36302c36312c36322c36332c36342c36352c36362c36372c36382c36392c37302c37312c37322c37332c37342c37352c37362c37372c37382c37392c38302c38312c38322c38332c38342c38352c38362c38372c38382c38392c39302c39312c39322c39332c39342c39352c39362c39372c39382c39392c3130302c3130312c3130322c3130332c3130342c3130352c3130362c3130372c3130382c3130392c3131302c3131312c3131322c3131332c3131342c3131352c3131362c3131372c3131382c3131392c3132302c3132312c3132322c3132332c3132342c3132352c3132362c3132372c3132382c3132392c3133302c3133312c3133322c3133332c3133342c3133352c3133362c3133372c3133382c3133392c3134302c3134312c3134322c3134332c3134342c3134352c3134362c3134372c3134382c3134392c3135302c3135312c3135322c3135332c3135342c3135352c3135362c3135372c3135382c3135392c3136302c3136312c3136322c3136332c3136342c3136352c3136362c3136372c3136382c3136392c3137302c3137312c3137322c3137332c3137342c3137352c3137362c3137372c3137382c3137392c3138302c3138312c3138322c3138332c3138342c3138352c3138362c3138372c3138382c3138392c3139302c3139312c3139322c3139332c3139342c3139352c3139362c3139372c3139382c3139392c3230302c3230312c3230322c3230332c3230342c3230352c3230362c3230372c3230382c3230392c3231302c3231312c3231322c3231332c3231342c3231352c3231362c3231372c3231382c3231392c3232302c3232312c3232322c3232332c3232342c3232352c3232362c3232372c3232382c3232392c3233302c3233312c3233322c3233332c3233342c3233352c3233362c3233372c3233382c3233392c3234302c3234312c3234322c3234332c3234342c3234352c3234362c3234372c3234382c3234392c3235302c3235312c3235322c3235332c3235342c3235352c3235362c3235372c3235382c3235392c3236302c3236312c3236322c3236332c3236342c3236352c3236362c3236372c3236382c3236392c3237302c3237312c3237322c3237332c3237342c3237352c3237362c3237372c3237382c3237392c3238302c3238312c3238322c3238332c3238342c3238352c3238362c3238372c3238382c3238392c3239302c3239312c3239322c3239332c3239342c3239352c3239362c3239372c3239382c3239392c3330302c3330312c3330322c3330332c3330342c3330352c3330362c3330372c3330382c3330392c3331302c3331312c3331322c3331332c3331342c3331352c3331362c3331372c3331382c3331392c3332302c3332312c3332322c3332332c3332342c3332352c3332362c3332372c3332382c3332392c3333302c3333312c3333322c3333332c3333342c3333352c3333362c3333372c3333382c3333392c3334302c3334312c3334322c3334332c3334342c3334352c3334362c3334372c3334382c3334392c3335302c3335312c3335322c3335332c3335342c3335352c3335362c3335372c3335382c3335392c3336302c3336312c3336322c3336332c3336342c3336352c3336362c3336372c3336382c3336392c3337302c3337312c3337322c3337332c3337342c3337352c3337362c3337372c3337382c3337392c3338302c3338312c3338322c3338332c3338342c3338352c3338362c3338372c3338382c3338392c3339302c3339312c3339322c3339332c3339342c3339352c3339362c3339372c3339382c3339392c3430302c3430312c3430322c3430332c3430342c3430352c3430362c3430372c3430382c3430392c3431302c3431312c3431322c3431332c3431342c3431352c3431362c3431372c3431382c3431392c3432302c3432312c3432322c3432332c3432342c3432352c3432362c3432372c3432382c3432392c3433302c3433312c3433322c3433332c3433342c3433352c3433362c3433372c3433382c3433392c3434302c3434312c3434322c3434332c3434342c3434352c3434362c3434372c3434382c3434392c3435302c3435312c3435322c3435332c3435342c3435352c3435362c3435372c3435382c3435392c3436302c3436312c3436322c3436332c3436342c3436352c3436362c3436372c3436382c3436392c3437302c3437312c3437322c3437332c3437342c3437352c3437362c3437372c3437382c3437392c3438302c3438312c3438322c3438332c3438342c3438352c3438362c3438372c3438382c3438392c3439302c3439312c3439322c3439332c3439342c3439352c3439362c3439372c3439382c3439392c3530302c3530312c3530322c3530332c3530342c3530352c3530362c3530372c3530382c3530392c3531302c3531312c3531322c3531332c3531342c3531352c3531362c3531372c3531382c3531392c3532302c3532312c3532322c3532332c3532342c3532352c3532362c3532372c3532382c3532392c3533302c3533312c3533322c3533332c3533342c3533352c3533362c3533372c3533382c3533392c3534302c3534312c3534322c3534332c3534342c3534352c3534362c3534372c3534382c3534392c3535302c3535312c3535322c3535332c3535342c3535352c3535362c3535372c3535382c3535392c3536302c3536312c3536322c3536332c3536342c3536352c3536362c3536372c3536382c3536392c3537302c3537312c3537322c3537332c3537342c3537352c3537362c3537372c3537382c3537392c3538302c3538312c3538322c3538332c3538342c3538352c3538362c3538372c3538382c3538392c3539302c3539312c3539322c3539332c3539342c3539352c3539362c3539372c3539382c3539392c3630302c3630312c3630322c3630332c3630342c3630352c3630362c3630372c3630382c3630392c3631302c3631312c3631322c3631332c3631342c3631352c3631362c3631372c3631382c3631392c3632302c3632312c3632322c3632332c3632342c3632352c3632362c3632372c3632382c3632392c3633302c3633312c3633322c3633332c3633342c3633352c3633362c3633372c3633382c3633392c3634302c3634312c3634322c3634332c3634342c3634352c3634362c3634372c3634382c3634392c3635302c3635312c3635322c3635332c3635342c3635352c3635362c3635372c3635382c3635392c3636302c3636312c3636322c3636332c3636342c3636352c3636362c3636372c3636382c3636392c3637302c3637312c3637322c3637332c3637342c3637352c3637362c3637372c3637382c3637392c3638302c3638312c3638322c3638332c3638342c3638352c3638362c3638372c3638382c3638392c3639302c3639312c3639322c3639332c3639342c3639352c3639362c3639372c3639382c3639392c3730302c3730312c3730322c3730332c3730342c3730352c3730362c3730372c3730382c3730392c3731302c3731312c3731322c3731332c3731342c3731352c3731362c3731372c3731382c3731392c3732302c3732312c3732322c3732332c3732342c3732352c3732362c3732372c3732382c3732392c3733302c3733312c3733322c3733332c3733342c3733352c3733362c3733372c3733382c3733392c3734302c3734312c3734322c3734332c3734342c3734352c3734362c3734372c3734382c3734392c3735302c3735312c3735322c3735332c3735342c3735352c3735362c3735372c3735382c3735392c3736302c3736312c3736322c3736332c3736342c3736352c3736362c3736372c3736382c3736392c3737302c3737312c3737322c3737332c3737342c3737352c3737362c3737372c3737382c3737392c3738302c3738312c3738322c3738332c3738342c3738352c3738362c3738372c3738382c3738392c3739302c3739312c3739322c3739332c3739342c3739352c3739362c3739372c3739382c3739392c3830302c3830312c3830322c3830332c3830342c3830352c3830362c3830372c3830382c3830392c3831302c3831312c3831322c3831332c3831342c3831352c3831362c3831372c3831382c3831392c3832302c3832312c3832322c3832332c3832342c3832352c3832362c3832372c3832382c3832392c3833302c3833312c3833322c3833332c3833342c3833352c3833362c3833372c3833382c3833392c3834302c3834312c3834322c3834332c3834342c3834352c3834362c3834372c3834382c3834392c3835302c3835312c3835322c3835332c3835342c3835352c3835362c3835372c3835382c3835392c3836302c3836312c3836322c3836332c3836342c3836352c3836362c3836372c3836382c3836392c3837302c3837312c3837322c3837332c3837342c3837352c3837362c3837372c3837382c3837392c3838302c3838312c3838322c3838332c3838342c3838352c3838362c3838372c3838382c3838392c3839302c3839312c3839322c3839332c3839342c3839352c3839362c3839372c3839382c3839392c3930302c3930312c3930322c3930332c3930342c3930352c3930362c3930372c3930382c3930392c3931302c3931312c3931322c3931332c3931342c3931352c3931362c3931372c3931382c3931392c3932302c3932312c3932322c3932332c3932342c3932352c3932362c3932372c3932382c3932392c3933302c3933312c3933322c3933332c3933342c3933352c3933362c3933372c3933382c3933392c3934302c3934312c3934322c3934332c3934342c3934352c3934362c3934372c3934382c3934392c3935302c3935312c3935322c3935332c3935342c3935352c3935362c3935372c3935382c3935392c3936302c3936312c3936322c3936332c3936342c3936352c3936362c3936372c3936382c3936392c3937302c3937312c3937322c3937332c3937342c3937352c3937362c3937372c3937382c3937392c3938302c3938312c3938322c3938332c3938342c3938352c3938362c3938372c3938382c3938392c3939302c3939312c3939322c3939332c3939342c3939352c3939362c3939372c3939382c3939392c313030302c313030312c313030322c313030332c313030342c313030352c313030362c313030372c313030382c313030392c313031302c313031312c313031322c313031332c313031342c313031352c313031362c313031372c313031382c313031392c313032302c313032312c313032322c313032332c313032345d2c7b226275666665725669657722203a20312c22636f6d706f6e656e745479706522203a20353132362c22636f756e7422203a2032342c227479706522203a202256454333227d2c7b2262756666657222203a20302c22627974654c656e67746822203a203238382c22627974654f666673657422203a20307d2c7b227062724d6574616c6c6963526f7567686e657373223a207b2262617365436f6c6f72466163746f72223a205b7b2262756666657222203a20302c22627974654c656e67746822203a203238382c22627974654f666673657422203a203238387d2c226d6174726978223a205b312e302c302e302c302e302c302e302c302e302c302e302c312e302c302e302c302e302c312e302c302e302c302e302c302e302c302e302c302e302c312e305d7d2ca164736f6c6343000809000a

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

0000000000000000000000008d04a8c79ceb0889bdd12acdf3fa9d207ed3ff630000000000000000000000000e4b8e24789630618aa90072f520711d3d9db647

-----Decoded View---------------
Arg [0] : _blitAddress (address): 0x8d04a8c79cEB0889Bdd12acdF3Fa9D207eD3Ff63
Arg [1] : _flipAddress (address): 0x0E4B8e24789630618aA90072F520711D3d9Db647

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000008d04a8c79ceb0889bdd12acdf3fa9d207ed3ff63
Arg [1] : 0000000000000000000000000e4b8e24789630618aa90072f520711d3d9db647


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.