ETH Price: $1,742.91 (+1.29%)
Gas: 26 Gwei

Contract

0xfDac77881ff861fF76a83cc43a1be3C317c6A1cC
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
Set Layers135561812021-11-05 10:59:53508 days 3 hrs ago1636109993IN
0xfDac77...17c6A1cC
0 ETH0.892633295
Set Layers135561702021-11-05 10:58:32508 days 3 hrs ago1636109912IN
0xfDac77...17c6A1cC
0 ETH1.0123461100
Set Layers135561462021-11-05 10:53:22508 days 3 hrs ago1636109602IN
0xfDac77...17c6A1cC
0 ETH1.28037338110
Set Layers135561052021-11-05 10:42:02508 days 3 hrs ago1636108922IN
0xfDac77...17c6A1cC
0 ETH0.7136317484
Set Layers135559792021-11-05 10:09:18508 days 4 hrs ago1636106958IN
0xfDac77...17c6A1cC
0 ETH0.7841111497
Set Layers135559622021-11-05 10:05:57508 days 4 hrs ago1636106757IN
0xfDac77...17c6A1cC
0 ETH0.9722613697
Set Layers135559082021-11-05 9:53:22508 days 4 hrs ago1636106002IN
0xfDac77...17c6A1cC
0 ETH1.2244341498
0x60806040135558732021-11-05 9:45:27508 days 4 hrs ago1636105527IN
 Create: ChainRunnersBaseRenderer
0 ETH0.7111922395

Advanced mode:
Parent Txn Hash Block From To Value
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChainRunnersBaseRenderer

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 5 : ChainRunnersBaseRenderer.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./core/ChainRunnersTypes.sol";

/*
               ::::                                                                                                                                                  :::#%=
               @*==+-                                                                                                                                               ++==*=.
               #+=#=++..                                                                                                                                        ..=*=*+-#:
                :=+++++++=====================================:    .===============================================. .=========================================++++++++=
                 .%-+%##+=--==================================+=..=+-=============================================-+*+======================================---+##+=#-.
                   [email protected]@%[email protected]@@%+++++++++++++++++++++++++++%#++++++%#+++#@@@#[email protected]@%[email protected]#+.=+*@*+*@@@@*+++++++++++++++++++++++%@@@#+++#@@+++=
                    -*-#%@@%%%=*%@%*++=++=+==+=++=++=+=++=++==#@%#%#+++=+=*@%*+=+==+=+++%*[email protected]%%#%#++++*@%#++=++=++=++=+=++=++=+=+*%%*==*%@@@*:%=
                     :@:[email protected]@@@@@*+++%@@*+===========+*=========#@@========+#%==========*@========##*#*+=======*@##*======#@#+=======*#*============+#%++#@@%#@@#++=.
                      .*+=%@%*%@%##[email protected]@%#=-==-=--==*%=========*%==--=--=-====--=--=-=##=--=-=--%%%%%+=-=--=-=*%=--=--=-=#%=--=----=#%=--=-=--=-+%#+==#%@@*#%@=++.
                        +%.#@@###%@@@@@%*---------#@%########@%*---------------------##---------------------##---------%%*[email protected]@#---------+#@=#@@#[email protected]@%*++-
                        .:*+*%@#+=*%@@@*=-------=#%#=-------=%*---------=*#*--------#+=--------===--------=#%*-------=#%*[email protected]%#--------=%@@%#*+=-+#%*+*:.
       ====================%*[email protected]@%#==+##%@*[email protected]#[email protected]@*-------=*@[email protected]@*[email protected][email protected]=--------*@@+-------+#@@%#==---+#@.*%====================
     :*=--==================-:=#@@%*===+*@%+=============%%%@=========*%@*[email protected]+=--=====+%@[email protected][email protected]========*%@@+======%%%**+=---=%@#=:-====================-#-
       +++**%@@@#*****************@#*=---=##%@@@@@@@@@@@@@#**@@@@****************%@@*[email protected]#***********#@************************************+=------=*@#*********************@#+=+:
        .-##=*@@%*----------------+%@%=---===+%@@@@@@@*+++---%#++----------------=*@@*+++=-----------=+#=------------------------------------------+%+--------------------+#@[email protected]
         :%:#%#####+=-=-*@@+--=-==-=*@=--=-==-=*@@#*[email protected][email protected]%===-==----+-==-==--+*+-==-==---=*@@@@@@%#===-=-=+%@%-==-=-==-#@%=-==-==--+#@@@@@@@@@@@@*+++
        =*=#@#=----==-=-=++=--=-==-=*@=--=-==-=*@@[email protected]===-=--=-*@@*[email protected]=--=-==--+#@-==-==---+%-==-==---=+++#@@@#--==-=-=++++-=--=-===#%[email protected]@@%.#*
        +#:@%*===================++%#=========%@%=========#%=========+#@%+=======#%==========*@#=========*%=========+*+%@@@+========+*[email protected]@%+**+================*%#*=+=
       *++#@*+=++++++*#%*+++++=+++*%%++++=++++%%*=+++++++##*=++++=++=%@@++++=++=+#%++++=++++#%@=+++++++=*#*+++++++=#%@@@@@*++=++++=#%@*[email protected]#*****=+++++++=+++++*%@@+:=+=
    :=*=#%#@@@@#%@@@%#@@#++++++++++%%*+++++++++++++++++**@*+++++++++*%#++++++++=*##++++++++*%@%+++++++++##+++++++++#%%%%%%++++**#@@@@@**+++++++++++++++++=*%@@@%#@@@@#%@@@%#@++*:.
    #*:@#=-+%#+:=*@*[email protected]%#++++++++#%@@#*++++++++++++++#%@#*++++++++*@@#[email protected]#++++++++*@@#+++++++++##*+++++++++++++++++###@@@@++*@@#+++++++++++++++++++*@@#=:+#%[email protected]*=-+%*[email protected]=
    ++=#%#+%@@%=#%@%#+%%#++++++*#@@@%###**************@@@++++++++**#@##*********#*********#@@#++++++***@#******%@%#*++**#@@@%##+==+++=*#**********%%*++++++++#%#=%@@%+*%@%*+%#*=*-
     .-*+===========*@@+++++*%%%@@@++***************+.%%*++++#%%%@@%=:=******************[email protected]@#+++*%%@#==+***--*@%*++*%@@*===+**=--   -************[email protected]%%#++++++#@@@*==========*+-
        =*******##.#%#++++*%@@@%+==+=             *#-%@%**%%###*====**-               [email protected]:*@@##@###*==+**-.-#[email protected]@#*@##*==+***=                     =+=##%@*+++++*%@@#.#%******:
               ++++%#+++*#@@@@+++==.              **[email protected]@@%+++++++===-                 -+++#@@+++++++==:  :+++%@@+++++++==:                          [email protected]%##[email protected]@%++++
             :%:*%%****%@@%+==*-                .%==*====**+...                      #*.#+==***....    #+=#%+==****:.                                ..-*=*%@%#++*#%@=+%.
            -+++#%+#%@@@#++===                  [email protected]*++===-                            #%++===           %#+++===                                          =+++%@%##**@@*[email protected]:
          .%-=%@##@@%*==++                                                                                                                                 .*==+#@@%*%@%=*=.
         .+++#@@@@@*++==.                                                                                                                                    -==++#@@@@@@=+%
       .=*=%@@%%%#=*=.                                                                                                                                          .*+=%@@@@%+-#.
       @[email protected]@@%:++++.                                                                                                                                              -+++**@@#+*=:
    .-+=*#%%++*::.                                                                                                                                                  :+**=#%@#==#
    #*:@*+++=:                                                                                                                                                          [email protected]*++=:
  :*-=*=++..                                                                                                                                                             .=*=#*.%=
 +#.=+++:                                                                                                                                                                   ++++:+#
*+=#-::                                                                                                                                                                      .::*+=*

*/

contract ChainRunnersBaseRenderer is Ownable, ReentrancyGuard {
    struct SVGCursor {
        uint8 x;
        uint8 y;
        string color1;
        string color2;
        string color3;
        string color4;
    }

    struct Buffer {
        string one;
        string two;
        string three;
        string four;
        string five;
        string six;
        string seven;
        string eight;
    }

    struct Color {
        string hexString;
        uint alpha;
        uint red;
        uint green;
        uint blue;
    }

    struct Layer {
        string name;
        bytes hexString;
    }

    struct LayerInput {
        string name;
        bytes hexString;
        uint8 layerIndex;
        uint8 itemIndex;
    }

    uint256 public constant NUM_LAYERS = 13;
    uint256 public constant NUM_COLORS = 8;

    mapping(uint256 => Layer) [NUM_LAYERS] layers;

    /*
    This indexes into a race, then a layer index, then an array capturing the frequency each layer should be selected.
    Shout out to Anonymice for the rarity impl inspiration.
    */
    uint16[][NUM_LAYERS][3] WEIGHTS;

    constructor() {
        // Default
        WEIGHTS[0][0] = [36, 225, 225, 225, 360, 135, 27, 360, 315, 315, 315, 315, 225, 180, 225, 180, 360, 180, 45, 360, 360, 360, 27, 36, 360, 45, 180, 360, 225, 360, 225, 225, 360, 180, 45, 360, 18, 225, 225, 225, 225, 180, 225, 361];
        WEIGHTS[0][1] = [875, 1269, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 17, 8, 41];
        WEIGHTS[0][2] = [303, 303, 303, 303, 151, 30, 0, 0, 151, 151, 151, 151, 30, 303, 151, 30, 303, 303, 303, 303, 303, 303, 30, 151, 303, 303, 303, 303, 303, 303, 303, 303, 3066];
        WEIGHTS[0][3] = [645, 0, 1290, 322, 645, 645, 645, 967, 322, 967, 645, 967, 967, 973];
        WEIGHTS[0][4] = [0, 0, 0, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250];
        WEIGHTS[0][5] = [121, 121, 121, 121, 121, 121, 243, 0, 0, 0, 0, 121, 121, 243, 121, 121, 243, 121, 121, 121, 121, 121, 243, 121, 121, 121, 121, 243, 121, 121, 121, 121, 243, 121, 121, 121, 243, 121, 121, 121, 121, 243, 121, 121, 121, 121, 243, 121, 121, 121, 121, 243, 121, 121, 121, 121, 243, 121, 121, 121, 121, 243, 121, 121, 243, 0, 0, 0, 121, 121, 243, 121, 121, 306];
        WEIGHTS[0][6] = [925, 555, 185, 555, 925, 925, 185, 1296, 1296, 1296, 1857];
        WEIGHTS[0][7] = [88, 88, 88, 88, 88, 265, 442, 8853];
        WEIGHTS[0][8] = [189, 189, 47, 18, 9, 28, 37, 9483];
        WEIGHTS[0][9] = [340, 340, 340, 340, 340, 340, 34, 340, 340, 340, 340, 170, 170, 170, 102, 238, 238, 238, 272, 340, 340, 340, 272, 238, 238, 238, 238, 170, 34, 340, 340, 136, 340, 340, 340, 340, 344];
        WEIGHTS[0][10] = [159, 212, 106, 53, 26, 159, 53, 265, 53, 212, 159, 265, 53, 265, 265, 212, 53, 159, 239, 53, 106, 5, 106, 53, 212, 212, 106, 159, 212, 265, 212, 265, 5066];
        WEIGHTS[0][11] = [139, 278, 278, 250, 250, 194, 222, 278, 278, 194, 222, 83, 222, 278, 139, 139, 27, 278, 278, 278, 278, 27, 278, 139, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 27, 139, 139, 139, 139, 0, 278, 194, 83, 83, 278, 83, 27, 306];
        WEIGHTS[0][12] = [981, 2945, 654, 16, 981, 327, 654, 163, 3279];

        // Skull
        WEIGHTS[1][0] = [36, 225, 225, 225, 360, 135, 27, 360, 315, 315, 315, 315, 225, 180, 225, 180, 360, 180, 45, 360, 360, 360, 27, 36, 360, 45, 180, 360, 225, 360, 225, 225, 360, 180, 45, 360, 18, 225, 225, 225, 225, 180, 225, 361];
        WEIGHTS[1][1] = [875, 1269, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 17, 8, 41];
        WEIGHTS[1][2] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000];
        WEIGHTS[1][3] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        WEIGHTS[1][4] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        WEIGHTS[1][5] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 384, 7692, 1923, 0, 0, 0, 0, 0, 1];
        WEIGHTS[1][6] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000];
        WEIGHTS[1][7] = [0, 0, 0, 0, 0, 909, 0, 9091];
        WEIGHTS[1][8] = [0, 0, 0, 0, 0, 0, 0, 10000];
        WEIGHTS[1][9] = [526, 526, 526, 0, 0, 0, 0, 0, 526, 0, 0, 0, 526, 0, 526, 0, 0, 0, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 0, 0, 526, 0, 0, 0, 0, 532];
        WEIGHTS[1][10] = [80, 0, 400, 240, 80, 0, 240, 0, 0, 80, 80, 80, 0, 0, 0, 0, 80, 80, 0, 0, 80, 80, 0, 80, 80, 80, 80, 80, 0, 0, 0, 0, 8000];
        WEIGHTS[1][11] = [289, 0, 0, 0, 0, 404, 462, 578, 578, 0, 462, 173, 462, 578, 0, 0, 57, 0, 57, 0, 57, 57, 578, 289, 578, 57, 0, 57, 57, 57, 578, 578, 0, 0, 0, 0, 0, 0, 57, 289, 578, 0, 0, 0, 231, 57, 0, 0, 1745];
        WEIGHTS[1][12] = [714, 714, 714, 0, 714, 0, 0, 0, 7144];

        // Bot
        WEIGHTS[2][0] = [36, 225, 225, 225, 360, 135, 27, 360, 315, 315, 315, 315, 225, 180, 225, 180, 360, 180, 45, 360, 360, 360, 27, 36, 360, 45, 180, 360, 225, 360, 225, 225, 360, 180, 45, 360, 18, 225, 225, 225, 225, 180, 225, 361];
        WEIGHTS[2][1] = [875, 1269, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 17, 8, 41];
        WEIGHTS[2][2] = [303, 303, 303, 303, 151, 30, 0, 0, 151, 151, 151, 151, 30, 303, 151, 30, 303, 303, 303, 303, 303, 303, 30, 151, 303, 303, 303, 303, 303, 303, 303, 303, 3066];
        WEIGHTS[2][3] = [645, 0, 1290, 322, 645, 645, 645, 967, 322, 967, 645, 967, 967, 973];
        WEIGHTS[2][4] = [2500, 2500, 2500, 0, 0, 0, 0, 0, 0, 2500, 0];
        WEIGHTS[2][5] = [0, 0, 0, 0, 0, 0, 588, 588, 588, 588, 588, 0, 0, 588, 0, 0, 588, 0, 0, 0, 0, 0, 588, 0, 0, 0, 0, 588, 0, 0, 0, 588, 588, 0, 0, 0, 588, 0, 0, 0, 0, 588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 588, 0, 0, 0, 0, 588, 0, 0, 0, 0, 588, 0, 0, 0, 0, 0, 0, 0, 0, 588, 0, 0, 4];
        WEIGHTS[2][6] = [925, 555, 185, 555, 925, 925, 185, 1296, 1296, 1296, 1857];
        WEIGHTS[2][7] = [88, 88, 88, 88, 88, 265, 442, 8853];
        WEIGHTS[2][8] = [183, 274, 274, 18, 18, 27, 36, 9170];
        WEIGHTS[2][9] = [340, 340, 340, 340, 340, 340, 34, 340, 340, 340, 340, 170, 170, 170, 102, 238, 238, 238, 272, 340, 340, 340, 272, 238, 238, 238, 238, 170, 34, 340, 340, 136, 340, 340, 340, 340, 344];
        WEIGHTS[2][10] = [217, 362, 217, 144, 72, 289, 144, 362, 72, 289, 217, 362, 72, 362, 362, 289, 0, 217, 0, 72, 144, 7, 217, 72, 217, 217, 289, 217, 289, 362, 217, 362, 3269];
        WEIGHTS[2][11] = [139, 278, 278, 250, 250, 194, 222, 278, 278, 194, 222, 83, 222, 278, 139, 139, 27, 278, 278, 278, 278, 27, 278, 139, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 27, 139, 139, 139, 139, 0, 278, 194, 83, 83, 278, 83, 27, 306];
        WEIGHTS[2][12] = [981, 2945, 654, 16, 981, 327, 654, 163, 3279];
    }

    function setLayers(LayerInput[] calldata toSet) external onlyOwner {
        for (uint16 i = 0; i < toSet.length; i++) {
            layers[toSet[i].layerIndex][toSet[i].itemIndex] = Layer(toSet[i].name, toSet[i].hexString);
        }
    }

    function getLayer(uint8 layerIndex, uint8 itemIndex) public view returns (Layer memory) {
        return layers[layerIndex][itemIndex];
    }

    /*
    Get race index.  Race index represents the "type" of base character:

    0 - Default, representing human and alien characters
    1 - Skull
    2 - Bot

    This allows skull/bot characters to have distinct trait distributions.
    */
    function getRaceIndex(uint16 _dna) public view returns (uint8) {
        uint16 lowerBound;
        uint16 percentage;
        for (uint8 i; i < WEIGHTS[0][1].length; i++) {
            percentage = WEIGHTS[0][1][i];
            if (_dna >= lowerBound && _dna < lowerBound + percentage) {
                if (i == 1) {
                    // Bot
                    return 2;
                } else if (i > 11) {
                    // Skull
                    return 1;
                } else {
                    // Default
                    return 0;
                }
            }
            lowerBound += percentage;
        }
        revert();
    }

    function getLayerIndex(uint16 _dna, uint8 _index, uint16 _raceIndex) public view returns (uint) {
        uint16 lowerBound;
        uint16 percentage;
        for (uint8 i; i < WEIGHTS[_raceIndex][_index].length; i++) {
            percentage = WEIGHTS[_raceIndex][_index][i];
            if (_dna >= lowerBound && _dna < lowerBound + percentage) {
                return i;
            }
            lowerBound += percentage;
        }
        // If not found, return index higher than available layers.  Will get filtered out.
        return WEIGHTS[_raceIndex][_index].length;
    }

    /*
    Generate base64 encoded tokenURI.

    All string constants are pre-base64 encoded to save gas.
    Input strings are padded with spacing/etc to ensure their length is a multiple of 3.
    This way the resulting base64 encoded string is a multiple of 4 and will not include any '=' padding characters,
    which allows these base64 string snippets to be concatenated with other snippets.
    */
    function tokenURI(uint256 tokenId, ChainRunnersTypes.ChainRunner memory runnerData) public view returns (string memory) {
        (Layer [NUM_LAYERS] memory tokenLayers, Color [NUM_COLORS][NUM_LAYERS] memory tokenPalettes, uint8 numTokenLayers, string[NUM_LAYERS] memory traitTypes) = getTokenData(runnerData.dna);
        string memory attributes;
        for (uint8 i = 0; i < numTokenLayers; i++) {
            attributes = string(abi.encodePacked(attributes,
                bytes(attributes).length == 0 ? 'eyAg' : 'LCB7',
                'InRyYWl0X3R5cGUiOiAi', traitTypes[i], 'IiwidmFsdWUiOiAi', tokenLayers[i].name, 'IiB9'
                ));
        }
        string[4] memory svgBuffers = tokenSVGBuffer(tokenLayers, tokenPalettes, numTokenLayers);
        return string(abi.encodePacked(
                'data:application/json;base64,eyAgImltYWdlX2RhdGEiOiAiPHN2ZyB2ZXJzaW9uPScxLjEnIHZpZXdCb3g9JzAgMCAzMjAgMzIwJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHNoYXBlLXJlbmRlcmluZz0nY3Jpc3BFZGdlcyc+',
                svgBuffers[0], svgBuffers[1], svgBuffers[2], svgBuffers[3],
                'PHN0eWxlPnJlY3R7d2lkdGg6MTBweDtoZWlnaHQ6MTBweDt9PC9zdHlsZT48L3N2Zz4gIiwgImF0dHJpYnV0ZXMiOiBb',
                attributes,
                'XSwgICAibmFtZSI6IlJ1bm5lciAj',
                Base64.encode(uintToByteString(tokenId, 6)),
                'IiwgImRlc2NyaXB0aW9uIjogIkNoYWluIFJ1bm5lcnMgYXJlIE1lZ2EgQ2l0eSByZW5lZ2FkZXMgMTAwJSBnZW5lcmF0ZWQgb24gY2hhaW4uIn0g'
            ));
    }

    function tokenSVG(uint256 _dna) public view returns (string memory) {
        (Layer [NUM_LAYERS] memory tokenLayers, Color [NUM_COLORS][NUM_LAYERS] memory tokenPalettes, uint8 numTokenLayers, string[NUM_LAYERS] memory traitTypes) = getTokenData(_dna);
        string[4] memory buffer256 = tokenSVGBuffer(tokenLayers, tokenPalettes, numTokenLayers);
        return string(abi.encodePacked(
                "PHN2ZyB2ZXJzaW9uPScxLjEnIHZpZXdCb3g9JzAgMCAzMiAzMicgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyBzaGFwZS1yZW5kZXJpbmc9J2NyaXNwRWRnZXMnIGhlaWdodD0nMTAwJScgd2lkdGg9JzEwMCUnICA+",
                buffer256[0], buffer256[1], buffer256[2], buffer256[3],
                "PHN0eWxlPnJlY3R7d2lkdGg6MXB4O2hlaWdodDoxcHg7fTwvc3R5bGU+PC9zdmc+"
            )
        );
    }

    function getTokenData(uint256 _dna) public view returns (Layer [NUM_LAYERS] memory tokenLayers, Color [NUM_COLORS][NUM_LAYERS] memory tokenPalettes, uint8 numTokenLayers, string [NUM_LAYERS] memory traitTypes) {
        uint16[NUM_LAYERS] memory dna = splitNumber(_dna);
        uint16 raceIndex = getRaceIndex(dna[1]);

        bool hasFaceAcc = dna[7] < (10000 - WEIGHTS[raceIndex][7][7]);
        bool hasMask = dna[8] < (10000 - WEIGHTS[raceIndex][8][7]);
        bool hasHeadBelow = dna[9] < (10000 - WEIGHTS[raceIndex][9][36]);
        bool hasHeadAbove = dna[11] < (10000 - WEIGHTS[raceIndex][11][48]);
        bool useHeadAbove = (dna[0] % 2) > 0;
        for (uint8 i = 0; i < NUM_LAYERS; i ++) {
            Layer memory layer = layers[i][getLayerIndex(dna[i], i, raceIndex)];
            if (layer.hexString.length > 0) {
                /*
                These conditions help make sure layer selection meshes well visually.
                1. If mask, no face/eye acc/mouth acc
                2. If face acc, no mask/mouth acc/face
                3. If both head above & head below, randomly choose one
                */
                if (((i == 2 || i == 12) && !hasMask && !hasFaceAcc) || (i == 7 && !hasMask) || (i == 10 && !hasMask) || (i < 2 || (i > 2 && i < 7) || i == 8 || i == 9 || i == 11)) {
                    if (hasHeadBelow && hasHeadAbove && (i == 9 && useHeadAbove) || (i == 11 && !useHeadAbove)) continue;
                    tokenLayers[numTokenLayers] = layer;
                    tokenPalettes[numTokenLayers] = palette(tokenLayers[numTokenLayers].hexString);
                    traitTypes[numTokenLayers] = ["QmFja2dyb3VuZCAg","UmFjZSAg","RmFjZSAg","TW91dGgg","Tm9zZSAg","RXllcyAg","RWFyIEFjY2Vzc29yeSAg","RmFjZSBBY2Nlc3Nvcnkg","TWFzayAg","SGVhZCBCZWxvdyAg","RXllIEFjY2Vzc29yeSAg","SGVhZCBBYm92ZSAg","TW91dGggQWNjZXNzb3J5"][i];
                    numTokenLayers++;
                }
            }
        }
        return (tokenLayers, tokenPalettes, numTokenLayers, traitTypes);
    }

    /*
    Generate svg rects, leaving un-concatenated to save a redundant concatenation in calling functions to reduce gas.
    Shout out to Blitmap for a lot of the inspiration for efficient rendering here.
    */
    function tokenSVGBuffer(Layer [NUM_LAYERS] memory tokenLayers, Color [NUM_COLORS][NUM_LAYERS] memory tokenPalettes, uint8 numTokenLayers) public pure returns (string[4] memory) {
        // Base64 encoded lookups into x/y position strings from 010 to 310.
        string[32] memory lookup = ["MDAw", "MDEw", "MDIw", "MDMw", "MDQw", "MDUw", "MDYw", "MDcw", "MDgw", "MDkw", "MTAw", "MTEw", "MTIw", "MTMw", "MTQw", "MTUw", "MTYw", "MTcw", "MTgw", "MTkw", "MjAw", "MjEw", "MjIw", "MjMw", "MjQw", "MjUw", "MjYw", "Mjcw", "Mjgw", "Mjkw", "MzAw", "MzEw"];
        SVGCursor memory cursor;

        /*
        Rather than concatenating the result string with itself over and over (e.g. result = abi.encodePacked(result, newString)),
        we fill up multiple levels of buffers.  This reduces redundant intermediate concatenations, performing O(log(n)) concats
        instead of O(n) concats.  Buffers beyond a length of about 12 start hitting stack too deep issues, so using a length of 8
        because the pixel math is convenient.
        */
        Buffer memory buffer4;
        // 4 pixels per slot, 32 total.  Struct is ever so slightly better for gas, so using when convenient.
        string[8] memory buffer32;
        // 32 pixels per slot, 256 total
        string[4] memory buffer256;
        // 256 pixels per slot, 1024 total
        uint8 buffer32count;
        uint8 buffer256count;
        for (uint k = 32; k < 416;) {
            cursor.color1 = colorForIndex(tokenLayers, k, 0, tokenPalettes, numTokenLayers);
            cursor.color2 = colorForIndex(tokenLayers, k, 1, tokenPalettes, numTokenLayers);
            cursor.color3 = colorForIndex(tokenLayers, k, 2, tokenPalettes, numTokenLayers);
            cursor.color4 = colorForIndex(tokenLayers, k, 3, tokenPalettes, numTokenLayers);
            buffer4.one = pixel4(lookup, cursor);
            cursor.x += 4;

            cursor.color1 = colorForIndex(tokenLayers, k, 4, tokenPalettes, numTokenLayers);
            cursor.color2 = colorForIndex(tokenLayers, k, 5, tokenPalettes, numTokenLayers);
            cursor.color3 = colorForIndex(tokenLayers, k, 6, tokenPalettes, numTokenLayers);
            cursor.color4 = colorForIndex(tokenLayers, k, 7, tokenPalettes, numTokenLayers);
            buffer4.two = pixel4(lookup, cursor);
            cursor.x += 4;

            k += 3;

            cursor.color1 = colorForIndex(tokenLayers, k, 0, tokenPalettes, numTokenLayers);
            cursor.color2 = colorForIndex(tokenLayers, k, 1, tokenPalettes, numTokenLayers);
            cursor.color3 = colorForIndex(tokenLayers, k, 2, tokenPalettes, numTokenLayers);
            cursor.color4 = colorForIndex(tokenLayers, k, 3, tokenPalettes, numTokenLayers);
            buffer4.three = pixel4(lookup, cursor);
            cursor.x += 4;

            cursor.color1 = colorForIndex(tokenLayers, k, 4, tokenPalettes, numTokenLayers);
            cursor.color2 = colorForIndex(tokenLayers, k, 5, tokenPalettes, numTokenLayers);
            cursor.color3 = colorForIndex(tokenLayers, k, 6, tokenPalettes, numTokenLayers);
            cursor.color4 = colorForIndex(tokenLayers, k, 7, tokenPalettes, numTokenLayers);
            buffer4.four = pixel4(lookup, cursor);
            cursor.x += 4;

            k += 3;

            cursor.color1 = colorForIndex(tokenLayers, k, 0, tokenPalettes, numTokenLayers);
            cursor.color2 = colorForIndex(tokenLayers, k, 1, tokenPalettes, numTokenLayers);
            cursor.color3 = colorForIndex(tokenLayers, k, 2, tokenPalettes, numTokenLayers);
            cursor.color4 = colorForIndex(tokenLayers, k, 3, tokenPalettes, numTokenLayers);
            buffer4.five = pixel4(lookup, cursor);
            cursor.x += 4;

            cursor.color1 = colorForIndex(tokenLayers, k, 4, tokenPalettes, numTokenLayers);
            cursor.color2 = colorForIndex(tokenLayers, k, 5, tokenPalettes, numTokenLayers);
            cursor.color3 = colorForIndex(tokenLayers, k, 6, tokenPalettes, numTokenLayers);
            cursor.color4 = colorForIndex(tokenLayers, k, 7, tokenPalettes, numTokenLayers);
            buffer4.six = pixel4(lookup, cursor);
            cursor.x += 4;

            k += 3;

            cursor.color1 = colorForIndex(tokenLayers, k, 0, tokenPalettes, numTokenLayers);
            cursor.color2 = colorForIndex(tokenLayers, k, 1, tokenPalettes, numTokenLayers);
            cursor.color3 = colorForIndex(tokenLayers, k, 2, tokenPalettes, numTokenLayers);
            cursor.color4 = colorForIndex(tokenLayers, k, 3, tokenPalettes, numTokenLayers);
            buffer4.seven = pixel4(lookup, cursor);
            cursor.x += 4;

            cursor.color1 = colorForIndex(tokenLayers, k, 4, tokenPalettes, numTokenLayers);
            cursor.color2 = colorForIndex(tokenLayers, k, 5, tokenPalettes, numTokenLayers);
            cursor.color3 = colorForIndex(tokenLayers, k, 6, tokenPalettes, numTokenLayers);
            cursor.color4 = colorForIndex(tokenLayers, k, 7, tokenPalettes, numTokenLayers);
            buffer4.eight = pixel4(lookup, cursor);
            cursor.x += 4;

            k += 3;

            buffer32[buffer32count++] = string(abi.encodePacked(buffer4.one, buffer4.two, buffer4.three, buffer4.four, buffer4.five, buffer4.six, buffer4.seven, buffer4.eight));
            cursor.x = 0;
            cursor.y += 1;
            if (buffer32count >= 8) {
                buffer256[buffer256count++] = string(abi.encodePacked(buffer32[0], buffer32[1], buffer32[2], buffer32[3], buffer32[4], buffer32[5], buffer32[6], buffer32[7]));
                buffer32count = 0;
            }
        }
        // At this point, buffer256 contains 4 strings or 256*4=1024=32x32 pixels
        return buffer256;
    }

    function palette(bytes memory data) internal pure returns (Color [NUM_COLORS] memory) {
        Color [NUM_COLORS] memory colors;
        for (uint16 i = 0; i < NUM_COLORS; i++) {
            // Even though this can be computed later from the RGBA values below, it saves gas to pre-compute it once upfront.
            colors[i].hexString = Base64.encode(bytes(abi.encodePacked(
                    byteToHexString(data[i * 4]),
                    byteToHexString(data[i * 4 + 1]),
                    byteToHexString(data[i * 4 + 2])
                )));
            colors[i].red = byteToUint(data[i * 4]);
            colors[i].green = byteToUint(data[i * 4 + 1]);
            colors[i].blue = byteToUint(data[i * 4 + 2]);
            colors[i].alpha = byteToUint(data[i * 4 + 3]);
        }
        return colors;
    }

    function colorForIndex(Layer[NUM_LAYERS] memory tokenLayers, uint k, uint index, Color [NUM_COLORS][NUM_LAYERS] memory palettes, uint numTokenLayers) internal pure returns (string memory) {
        for (uint256 i = numTokenLayers - 1; i >= 0; i--) {
            Color memory fg = palettes[i][colorIndex(tokenLayers[i].hexString, k, index)];
            // Since most layer pixels are transparent, performing this check first saves gas
            if (fg.alpha == 0) {
                continue;
            } else if (fg.alpha == 255) {
                return fg.hexString;
            } else {
                for (uint256 j = i - 1; j >= 0; j--) {
                    Color memory bg = palettes[j][colorIndex(tokenLayers[j].hexString, k, index)];
                    /* As a simplification, blend with first non-transparent layer then stop.
                    We won't generally have overlapping semi-transparent pixels.
                    */
                    if (bg.alpha > 0) {
                        return Base64.encode(bytes(blendColors(fg, bg)));
                    }
                }
            }
        }
        return "000000";
    }

    /*
    Each color index is 3 bits (there are 8 colors, so 3 bits are needed to index into them).
    Since 3 bits doesn't divide cleanly into 8 bits (1 byte), we look up colors 24 bits (3 bytes) at a time.
    "k" is the starting byte index, and "index" is the color index within the 3 bytes starting at k.
    */
    function colorIndex(bytes memory data, uint k, uint index) internal pure returns (uint8) {
        if (index == 0) {
            return uint8(data[k]) >> 5;
        } else if (index == 1) {
            return (uint8(data[k]) >> 2) % 8;
        } else if (index == 2) {
            return ((uint8(data[k]) % 4) * 2) + (uint8(data[k + 1]) >> 7);
        } else if (index == 3) {
            return (uint8(data[k + 1]) >> 4) % 8;
        } else if (index == 4) {
            return (uint8(data[k + 1]) >> 1) % 8;
        } else if (index == 5) {
            return ((uint8(data[k + 1]) % 2) * 4) + (uint8(data[k + 2]) >> 6);
        } else if (index == 6) {
            return (uint8(data[k + 2]) >> 3) % 8;
        } else {
            return uint8(data[k + 2]) % 8;
        }
    }

    /*
    Create 4 svg rects, pre-base64 encoding the svg constants to save gas.
    */
    function pixel4(string[32] memory lookup, SVGCursor memory cursor) internal pure returns (string memory result) {
        return string(abi.encodePacked(
                "PHJlY3QgICBmaWxsPScj", cursor.color1, "JyAgeD0n", lookup[cursor.x], "JyAgeT0n", lookup[cursor.y],
                "JyAvPjxyZWN0ICBmaWxsPScj", cursor.color2, "JyAgeD0n", lookup[cursor.x + 1], "JyAgeT0n", lookup[cursor.y],
                "JyAvPjxyZWN0ICBmaWxsPScj", cursor.color3, "JyAgeD0n", lookup[cursor.x + 2], "JyAgeT0n", lookup[cursor.y],
                "JyAvPjxyZWN0ICBmaWxsPScj", cursor.color4, "JyAgeD0n", lookup[cursor.x + 3], "JyAgeT0n", lookup[cursor.y], "JyAgIC8+"
            ));
    }

    /*
    Blend colors, inspired by https://stackoverflow.com/a/12016968
    */
    function blendColors(Color memory fg, Color memory bg) internal pure returns (string memory) {
        uint alpha = uint16(fg.alpha + 1);
        uint inv_alpha = uint16(256 - fg.alpha);
        return uintToHexString6(uint24((alpha * fg.blue + inv_alpha * bg.blue) >> 8) + (uint24((alpha * fg.green + inv_alpha * bg.green) >> 8) << 8) + (uint24((alpha * fg.red + inv_alpha * bg.red) >> 8) << 16));
    }

    function splitNumber(uint256 _number) internal pure returns (uint16[NUM_LAYERS] memory numbers) {
        for (uint256 i = 0; i < numbers.length; i++) {
            numbers[i] = uint16(_number % 10000);
            _number >>= 14;
        }
        return numbers;
    }

    function uintToHexDigit(uint8 d) public pure returns (bytes1) {
        if (0 <= d && d <= 9) {
            return bytes1(uint8(bytes1('0')) + d);
        } else if (10 <= uint8(d) && uint8(d) <= 15) {
            return bytes1(uint8(bytes1('a')) + d - 10);
        }
        revert();
    }

    /*
    Convert uint to hex string, padding to 6 hex nibbles
    */
    function uintToHexString6(uint a) public pure returns (string memory) {
        string memory str = uintToHexString2(a);
        if (bytes(str).length == 2) {
            return string(abi.encodePacked("0000", str));
        } else if (bytes(str).length == 3) {
            return string(abi.encodePacked("000", str));
        } else if (bytes(str).length == 4) {
            return string(abi.encodePacked("00", str));
        } else if (bytes(str).length == 5) {
            return string(abi.encodePacked("0", str));
        }
        return str;
    }

    /*
    Convert uint to hex string, padding to 2 hex nibbles
    */
    function uintToHexString2(uint a) public pure returns (string memory) {
        uint count = 0;
        uint b = a;
        while (b != 0) {
            count++;
            b /= 16;
        }
        bytes memory res = new bytes(count);
        for (uint i = 0; i < count; ++i) {
            b = a % 16;
            res[count - i - 1] = uintToHexDigit(uint8(b));
            a /= 16;
        }

        string memory str = string(res);
        if (bytes(str).length == 0) {
            return "00";
        } else if (bytes(str).length == 1) {
            return string(abi.encodePacked("0", str));
        }
        return str;
    }

    /*
    Convert uint to byte string, padding number string with spaces at end.
    Useful to ensure result's length is a multiple of 3, and therefore base64 encoding won't
    result in '=' padding chars.
    */
    function uintToByteString(uint a, uint fixedLen) internal pure returns (bytes memory _uintAsString) {
        uint j = a;
        uint len;
        while (j != 0) {
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(fixedLen);
        j = fixedLen;
        if (a == 0) {
            bstr[0] = "0";
            len = 1;
        }
        while (j > len) {
            j = j - 1;
            bstr[j] = bytes1(' ');
        }
        uint k = len;
        while (a != 0) {
            k = k - 1;
            uint8 temp = (48 + uint8(a - a / 10 * 10));
            bytes1 b1 = bytes1(temp);
            bstr[k] = b1;
            a /= 10;
        }
        return bstr;
    }

    function byteToUint(bytes1 b) public pure returns (uint) {
        return uint(uint8(b));
    }

    function byteToHexString(bytes1 b) public pure returns (string memory) {
        return uintToHexString2(byteToUint(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 5 : 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 3 of 5 : 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 4 of 5 : ChainRunnersTypes.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

interface ChainRunnersTypes {
    struct ChainRunner {
        uint256 dna;
    }
}

File 5 of 5 : 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;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 2000,
    "details": {
      "yul": true,
      "yulDetails": {
        "stackAllocation": true,
        "optimizerSteps": "dhfoDgvulfnTUtnIf"
      }
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"NUM_COLORS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NUM_LAYERS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes1","name":"b","type":"bytes1"}],"name":"byteToHexString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes1","name":"b","type":"bytes1"}],"name":"byteToUint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint8","name":"layerIndex","type":"uint8"},{"internalType":"uint8","name":"itemIndex","type":"uint8"}],"name":"getLayer","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"hexString","type":"bytes"}],"internalType":"struct ChainRunnersBaseRenderer.Layer","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dna","type":"uint16"},{"internalType":"uint8","name":"_index","type":"uint8"},{"internalType":"uint16","name":"_raceIndex","type":"uint16"}],"name":"getLayerIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dna","type":"uint16"}],"name":"getRaceIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dna","type":"uint256"}],"name":"getTokenData","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"hexString","type":"bytes"}],"internalType":"struct ChainRunnersBaseRenderer.Layer[13]","name":"tokenLayers","type":"tuple[13]"},{"components":[{"internalType":"string","name":"hexString","type":"string"},{"internalType":"uint256","name":"alpha","type":"uint256"},{"internalType":"uint256","name":"red","type":"uint256"},{"internalType":"uint256","name":"green","type":"uint256"},{"internalType":"uint256","name":"blue","type":"uint256"}],"internalType":"struct ChainRunnersBaseRenderer.Color[8][13]","name":"tokenPalettes","type":"tuple[8][13]"},{"internalType":"uint8","name":"numTokenLayers","type":"uint8"},{"internalType":"string[13]","name":"traitTypes","type":"string[13]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"hexString","type":"bytes"},{"internalType":"uint8","name":"layerIndex","type":"uint8"},{"internalType":"uint8","name":"itemIndex","type":"uint8"}],"internalType":"struct ChainRunnersBaseRenderer.LayerInput[]","name":"toSet","type":"tuple[]"}],"name":"setLayers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_dna","type":"uint256"}],"name":"tokenSVG","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes","name":"hexString","type":"bytes"}],"internalType":"struct ChainRunnersBaseRenderer.Layer[13]","name":"tokenLayers","type":"tuple[13]"},{"components":[{"internalType":"string","name":"hexString","type":"string"},{"internalType":"uint256","name":"alpha","type":"uint256"},{"internalType":"uint256","name":"red","type":"uint256"},{"internalType":"uint256","name":"green","type":"uint256"},{"internalType":"uint256","name":"blue","type":"uint256"}],"internalType":"struct ChainRunnersBaseRenderer.Color[8][13]","name":"tokenPalettes","type":"tuple[8][13]"},{"internalType":"uint8","name":"numTokenLayers","type":"uint8"}],"name":"tokenSVGBuffer","outputs":[{"internalType":"string[4]","name":"","type":"string[4]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"dna","type":"uint256"}],"internalType":"struct ChainRunnersTypes.ChainRunner","name":"runnerData","type":"tuple"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"d","type":"uint8"}],"name":"uintToHexDigit","outputs":[{"internalType":"bytes1","name":"","type":"bytes1"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"uintToHexString2","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"}],"name":"uintToHexString6","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]

60806040523480156200001157600080fd5b506200001d3362002413565b600180556040805161058081018252602480825260e1602083018190529282018390526060820183905261016860808301819052608760a0840152601b60c0840181905260e0840182905261013b610100850181905261012085018190526101408501819052610160850152610180840185905260b46101a085018190526101c085018690526101e0850181905261020085018390526102208501819052602d6102408601819052610260860184905261028086018490526102a086018490526102c08601929092526102e0850193909352610300840182905261032084018190526103408401839052610360840182905261038084018590526103a084018290526103c084018590526103e084018590526104008401829052610420840183905261044084015261046083015260126104808301526104a082018390526104c082018390526104e0820183905261050082018390526105208201526105408101919091526101696105608201526200019b90600f90602c62002463565b50604080516101e08101825261036b81526104f5602082015261030b918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810191909152601161018082015260086101a082015260296101c08201526200022990601090600f62002463565b50604080516104208101825261012f8082526020820181905291810182905260608101829052609760808201819052601e60a08301819052600060c0840181905260e0840152610100830182905261012083018290526101408301829052610160830182905261018083018190526101a083018490526101c083018290526101e08301819052610200830184905261022083018490526102408301849052610260830184905261028083018490526102a083018490526102c08301526102e0820152610300810182905261032081018290526103408101829052610360810182905261038081018290526103a081018290526103c081018290526103e0810191909152610bfa6104008201526200034590601190602162002463565b50604080516101c0810182526102858082526000602083015261050a92820192909252610142606082018190526080820183905260a0820183905260c082018390526103c760e08301819052610100830191909152610120820181905261014082019290925261016081018290526101808101919091526103cd6101a0820152620003d590601290600e62002463565b506040805161016081018252600080825260208201819052918101919091526104e2606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082018190526101408201526200044090601390600b62002463565b506040805161094081018252607980825260208201819052918101829052606081018290526080810182905260a0810182905260f360c08201819052600060e08301819052610100830181905261012083018190526101408301819052610160830184905261018083018490526101a083018290526101c083018490526101e08301849052610200830182905261022083018490526102408301849052610260830184905261028083018490526102a083018490526102c083018290526102e08301849052610300830184905261032083018490526103408301849052610360830182905261038083018490526103a083018490526103c083018490526103e08301849052610400830182905261042083018490526104408301849052610460830184905261048083018290526104a083018490526104c083018490526104e08301849052610500830184905261052083018290526105408301849052610560830184905261058083018490526105a083018490526105c083018290526105e08301849052610600830184905261062083018490526106408301849052610660830182905261068083018490526106a083018490526106c083018490526106e08301849052610700830182905261072083018490526107408301849052610760830184905261078083018490526107a083018290526107c083018490526107e0830184905261080083018290526108208301819052610840830181905261086083015261088082018390526108a082018390526108c08201526108e08101829052610900810191909152610132610920820152620006a390601490604a62002463565b50604080516101608101825261039d80825261022b6020830181905260b993830184905260608301526080820181905260a082015260c081019190915261051060e0820181905261010082018190526101208201526107416101408201526200071190601590600b62002463565b50604080516101008101825260588082526020820181905291810182905260608101829052608081019190915261010960a08201526101ba60c082015261229560e08201526200076690601690600862002463565b50604080516101008101825260bd8082526020820152602f918101919091526012606082015260096080820152601c60a0820152602560c082015261250b60e0820152620007b990601790600862002463565b50604080516104a08101825261015480825260208201819052918101829052606081018290526080810182905260a08101829052602260c0820181905260e0820183905261010082018390526101208201839052610140820183905260aa610160830181905261018083018190526101a0830181905260666101c084015260ee6101e08401819052610200840181905261022084018190526101106102408501819052610260850186905261028085018690526102a085018690526102c08501526102e08401819052610300840181905261032084018190526103408401526103608301526103808201526103a081018290526103c0810182905260886103e0820152610400810182905261042081018290526104408101829052610460810191909152610158610480820152620008f690601890602562002463565b506040805161042081018252609f80825260d460208301819052606a938301849052603560608401819052601a608085015260a0840183905260c0840181905261010960e08501819052610100850182905261012085018390526101408501849052610160850181905261018085018290526101a085018190526101c085018190526101e085018390526102008501829052610220850184905260ef6102408601526102608501829052610280850186905260056102a08601526102c085018690526102e08501919091526103008401829052610320840182905261034084019490945261036083019190915261038082018190526103a082018390526103c08201526103e08101919091526113ca61040082015262000a1b90601990602162002463565b506040805161062081018252608b8082526101166020830181905292820183905260fa60608301819052608083015260c260a0830181905260de60c0840181905260e08401859052610100840185905261012084018290526101408401819052605361016085018190526101808501919091526101a084018590526101c084018390526101e08401839052601b610200850181905261022085018690526102408501869052610260850186905261028085018690526102a085018190526102c085018690526102e08501849052610300850186905261032085018690526103408501869052610360850186905261038085018690526103a085018690526103c085018690526103e08501869052610400850186905261042085018690526104408501869052610460850181905261048085018490526104a085018490526104c085018490526104e085019390935260006105008501526105208401859052610540840191909152610560830181905261058083018190526105a08301939093526105c08201929092526105e081019190915261013261060082015262000bc690601a90603162002463565b5060408051610120810182526103d5808252610b81602083015261028e92820183905260106060830152608082015261014760a082015260c081019190915260a360e0820152610ccf61010082015262000c2590601b90600962002463565b506040805161058081018252602480825260e1602083018190529282018390526060820183905261016860808301819052608760a0840152601b60c0840181905260e0840182905261013b610100850181905261012085018190526101408501819052610160850152610180840185905260b46101a085018190526101c085018690526101e0850181905261020085018390526102208501819052602d6102408601819052610260860184905261028086018490526102a086018490526102c08601929092526102e0850193909352610300840182905261032084018190526103408401839052610360840182905261038084018590526103a084018290526103c084018590526103e084018590526104008401829052610420840183905261044084015261046083015260126104808301526104a082018390526104c082018390526104e08201839052610500820183905261052082015261054081019190915261016961056082015262000da090601c90602c62002463565b50604080516101e08101825261036b81526104f5602082015261030b918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810191909152601161018082015260086101a082015260296101c082015262000e2e90601d90600f62002463565b506040805161042081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e08101829052610200810182905261022081018290526102408101829052610260810182905261028081018290526102a081018290526102c081018290526102e08101829052610300810182905261032081018290526103408101829052610360810182905261038081018290526103a081018290526103c081018290526103e081019190915261271061040082015262000f4990601e90602162002463565b50604080516101c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915262000fcb90601f90600e62002513565b50604080516101608101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e0820181905261010082018190526101208201819052610140820152620010319190600b62002513565b506040805161094081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290526101808082018390526101a082018390526101c082018390526101e08201839052610200820183905261022082018390526102408201839052610260820183905261028082018390526102a082018390526102c082018390526102e08201839052610300820183905261032082018390526103408201839052610360820183905261038082018390526103a082018390526103c082018390526103e08201839052610400820183905261042082018390526104408201839052610460820183905261048082018390526104a082018390526104c082018390526104e08201839052610500820183905261052082018390526105408201839052610560820183905261058082018390526105a082018390526105c082018390526105e08201839052610600820183905261062082018390526106408201839052610660820183905261068082018390526106a082018390526106c082018390526106e08201839052610700820183905261072082018390526107408201839052610760820183905261078082018390526107a082018390526107c082018390526107e082018390526108008201839052610820820152611e0c61084082015261078361086082015261088081018290526108a081018290526108c081018290526108e0810182905261090081019190915260016109208201526200129490602190604a62002463565b506040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152612710610140820152620012ff90602290600b62002463565b506040805161010081018252600080825260208201819052918101829052606081018290526080810182905261038d60a082015260c081019190915261238360e08201526200135390602390600862002463565b506040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915261271060e0820152620013a690602490600862002463565b50604080516104a08101825261020e808252602082018190529181018290526000606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820183905261012082018190526101408201819052610160820181905261018082018390526101a082018190526101c082018390526101e08201819052610200820181905261022082018190526102408201839052610260820183905261028082018390526102a082018390526102c082018390526102e08201839052610300820183905261032082018390526103408201839052610360820183905261038082018390526103a082018190526103c082018190526103e0820192909252610400810182905261042081018290526104408101829052610460810191909152610214610480820152620014e4906025908162002463565b50604080516104208101825260508082526000602083018190526101909383019390935260f0606083018190526080830182905260a0830184905260c083015260e08201839052610100820183905261012082018190526101408201819052610160820181905261018082018390526101a082018390526101c082018390526101e08201839052610200820181905261022082018190526102408201839052610260820183905261028082018190526102a082018190526102c082018390526102e0820181905261030082018190526103208201819052610340820181905261036082015261038081018290526103a081018290526103c081018290526103e0810191909152611f406104008201526200160390602690602162002463565b506040805161062081018252610121808252600060208301819052928201839052606082018390526080820183905261019460a08301526101ce60c0830181905261024260e0840181905261010084018190526101208401859052610140840182905260ad6101608501526101808401919091526101a083018190526101c083018490526101e083018490526039610200840181905261022084018590526102408401819052610260840185905261028084018190526102a084018190526102c084018290526102e08401839052610300840182905261032084018190526103408401859052610360840181905261038084018190526103a084018190526103c084018290526103e08401829052610400840185905261042084018590526104408401859052610460840185905261048084018590526104a084018590526104c084018190526104e084019290925261050083015261052082018390526105408201839052610560820183905260e76105808301526105a08201526105c081018290526105e08101919091526106d1610600820152620017a890602790603162002463565b5060408051610120810182526102ca80825260208201819052918101829052600060608201819052608082019290925260a0810182905260c0810182905260e0810191909152611be86101008201526200180790602890600962002463565b506040805161058081018252602480825260e1602083018190529282018390526060820183905261016860808301819052608760a0840152601b60c0840181905260e0840182905261013b610100850181905261012085018190526101408501819052610160850152610180840185905260b46101a085018190526101c085018690526101e0850181905261020085018390526102208501819052602d6102408601819052610260860184905261028086018490526102a086018490526102c08601929092526102e0850193909352610300840182905261032084018190526103408401839052610360840182905261038084018590526103a084018290526103c084018590526103e084018590526104008401829052610420840183905261044084015261046083015260126104808301526104a082018390526104c082018390526104e0820183905261050082018390526105208201526105408101919091526101696105608201526200198290602990602c62002463565b50604080516101e08101825261036b81526104f5602082015261030b918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810191909152601161018082015260086101a082015260296101c082015262001a1090602a90600f62002463565b50604080516104208101825261012f8082526020820181905291810182905260608101829052609760808201819052601e60a08301819052600060c0840181905260e0840152610100830182905261012083018290526101408301829052610160830182905261018083018190526101a083018490526101c083018290526101e08301819052610200830184905261022083018490526102408301849052610260830184905261028083018490526102a083018490526102c08301526102e0820152610300810182905261032081018290526103408101829052610360810182905261038081018290526103a081018290526103c081018290526103e0810191909152610bfa61040082015262001b2c90602b90602162002463565b50604080516101c0810182526102858082526000602083015261050a92820192909252610142606082018190526080820183905260a0820183905260c082018390526103c760e08301819052610100830191909152610120820181905261014082019290925261016081018290526101808101919091526103cd6101a082015262001bbc90602c90600e62002463565b5060408051610160810182526109c4808252602082018190529181018290526000606082018190526080820181905260a0820181905260c0820181905260e08201819052610100820181905261012082019290925261014081019190915262001c2a90602d90600b62002463565b506040805161094081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905261024c60c0820181905260e08201819052610100820181905261012082018190526101408201819052610160820183905261018082018390526101a082018190526101c082018390526101e08201839052610200820181905261022082018390526102408201839052610260820183905261028082018390526102a082018390526102c082018190526102e08201839052610300820183905261032082018390526103408201839052610360820181905261038082018390526103a082018390526103c082018390526103e08201819052610400820181905261042082018390526104408201839052610460820183905261048082018190526104a082018390526104c082018390526104e08201839052610500820183905261052082018190526105408201839052610560820183905261058082018390526105a082018390526105c082018390526105e08201839052610600820183905261062082018390526106408201839052610660820181905261068082018390526106a082018390526106c082018390526106e08201839052610700820181905261072082018390526107408201839052610760820183905261078082018390526107a082018190526107c082018390526107e08201839052610800820183905261082082018390526108408201839052610860820183905261088082018390526108a082018390526108c08201526108e08101829052610900810191909152600461092082015262001e8d90602e90604a62002463565b50604080516101608101825261039d80825261022b6020830181905260b993830184905260608301526080820181905260a082015260c081019190915261051060e08201819052610100820181905261012082015261074161014082015262001efb90602f90600b62002463565b50604080516101008101825260588082526020820181905291810182905260608101829052608081019190915261010960a08201526101ba60c082015261229560e082015262001f5090603090600862002463565b50604080516101008101825260b7815261011260208201819052918101919091526012606082018190526080820152601b60a0820152602460c08201526123d260e082015262001fa590603190600862002463565b50604080516104a08101825261015480825260208201819052918101829052606081018290526080810182905260a08101829052602260c0820181905260e0820183905261010082018390526101208201839052610140820183905260aa610160830181905261018083018190526101a0830181905260666101c084015260ee6101e08401819052610200840181905261022084018190526101106102408501819052610260850186905261028085018690526102a085018690526102c08501526102e08401819052610300840181905261032084018190526103408401526103608301526103808201526103a081018290526103c0810182905260886103e0820152610400810182905261042081018290526104408101829052610460810191909152610158610480820152620020e290603290602562002463565b50604080516104208101825260d980825261016a6020830181905292820181905260906060830181905260486080840181905261012160a0850181905260c0850183905260e08501869052610100850182905261012085018190526101408501849052610160850186905261018085018290526101a085018690526101c085018690526101e08501819052600061020086018190526102208601859052610240860152610260850182905261028085019290925260076102a08501526102c084018390526102e084015261030083018290526103208301829052610340830181905261036083018290526103808301526103a082018390526103c08201526103e0810191909152610cc56104008201526200220290603390602162002463565b506040805161062081018252608b8082526101166020830181905292820183905260fa60608301819052608083015260c260a0830181905260de60c0840181905260e08401859052610100840185905261012084018290526101408401819052605361016085018190526101808501919091526101a084018590526101c084018390526101e08401839052601b610200850181905261022085018690526102408501869052610260850186905261028085018690526102a085018190526102c085018690526102e08501849052610300850186905261032085018690526103408501869052610360850186905261038085018690526103a085018690526103c085018690526103e08501869052610400850186905261042085018690526104408501869052610460850181905261048085018490526104a085018490526104c085018490526104e085019390935260006105008501526105208401859052610540840191909152610560830181905261058083018190526105a08301939093526105c08201929092526105e0810191909152610132610600820152620023ad90603490603162002463565b5060408051610120810182526103d5808252610b81602083015261028e92820183905260106060830152608082015261014760a082015260c081019190915260a360e0820152610ccf6101008201526200240c90603590600962002463565b5062002595565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090600f01601090048101928215620025015791602002820160005b83821115620024cf57835183826101000a81548161ffff021916908361ffff16021790555092602001926002016020816001010492830192600103026200248d565b8015620024ff5782816101000a81549061ffff0219169055600201602081600101049283019260010302620024cf565b505b506200250f9291506200257e565b5090565b82805482825590600052602060002090600f01601090048101928215620025015791602002820160005b83821115620024cf57835183826101000a81548161ffff021916908360ff16021790555092602001926002016020816001010492830192600103026200253d565b5b808211156200250f57600081556001016200257f565b614aee80620025a56000396000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c8063a62f8deb116100b2578063da8343c911610081578063f2fde38b11610066578063f2fde38b146102b4578063fca228ce146102c7578063ffbcaa51146102da57600080fd5b8063da8343c91461028d578063e9703701146102a057600080fd5b8063a62f8deb14610224578063b09afec114610237578063d129beee1461025a578063d68cf31f1461027a57600080fd5b80637249db4d116101095780637f436b5c116100ee5780637f436b5c146101cb5780638da5cb5b146101eb5780639bac5f7a1461021157600080fd5b80637249db4d146101ae5780637e8e0657146101c357600080fd5b80633ef21a5e1461013b5780634489fb2a146101645780637148ede114610184578063715018a6146101a4575b600080fd5b61014e6101493660046138ff565b6102ed565b60405161015b91906145b3565b60405180910390f35b6101776101723660046139ec565b610302565b60405161015b919061460e565b610197610192366004613884565b610486565b60405161015b9190614544565b6101ac611171565b005b6101b6600881565b60405161015b919061461f565b6101b6600d81565b6101de6101d936600461391c565b6111bd565b60405161015b919061462d565b60005473ffffffffffffffffffffffffffffffffffffffff1660405161015b9190614536565b61014e61021f36600461397a565b6112a6565b61014e610232366004613997565b61130d565b61024a61024536600461397a565b6114b1565b60405161015b9493929190614555565b61026d6102683660046139cf565b611dca565b60405161015b91906145a5565b61014e61028836600461397a565b611e1f565b6101ac61029b366004613842565b611eb1565b6101b66102ae3660046138ff565b60f81c90565b6101ac6102c2366004613825565b612108565b6101b66102d5366004613939565b61217e565b61014e6102e836600461397a565b612320565b60606102fc6102e88360f81c90565b92915050565b604080518082019091526060808252602082015260028360ff16600d811061033a57634e487b7160e01b600052603260045260246000fd5b0160008360ff16815260200190815260200160002060405180604001604052908160008201805461036a906148f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610396906148f5565b80156103e35780601f106103b8576101008083540402835291602001916103e3565b820191906000526020600020905b8154815290600101906020018083116103c657829003601f168201915b505050505081526020016001820180546103fc906148f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610428906148f5565b80156104755780601f1061044a57610100808354040283529160200191610475565b820191906000526020600020905b81548152906001019060200180831161045857829003601f168201915b505050505081525050905092915050565b61048e6132a4565b6040805161044081018252600461040082018181527f4d444177000000000000000000000000000000000000000000000000000000006104208401528252825180840184528181527f4d4445770000000000000000000000000000000000000000000000000000000060208281019190915280840191909152835180850185528281527f4d444977000000000000000000000000000000000000000000000000000000008183015283850152835180850185528281527f4d444d770000000000000000000000000000000000000000000000000000000081830152606080850191909152845180860186528381527f4d4451770000000000000000000000000000000000000000000000000000000081840152608080860191909152855180870187528481527f4d445577000000000000000000000000000000000000000000000000000000008185015260a080870191909152865180880188528581527f4d445977000000000000000000000000000000000000000000000000000000008186015260c080880191909152875180890189528681527f4d446377000000000000000000000000000000000000000000000000000000008187015260e0880152875180890189528681527f4d4467770000000000000000000000000000000000000000000000000000000081870152610100880152875180890189528681527f4d446b770000000000000000000000000000000000000000000000000000000081870152610120880152875180890189528681527f4d5441770000000000000000000000000000000000000000000000000000000081870152610140880152875180890189528681527f4d5445770000000000000000000000000000000000000000000000000000000081870152610160880152875180890189528681527f4d5449770000000000000000000000000000000000000000000000000000000081870152610180880152875180890189528681527f4d544d7700000000000000000000000000000000000000000000000000000000818701526101a0880152875180890189528681527f4d54517700000000000000000000000000000000000000000000000000000000818701526101c0880152875180890189528681527f4d54557700000000000000000000000000000000000000000000000000000000818701526101e0880152875180890189528681527f4d5459770000000000000000000000000000000000000000000000000000000081870152610200880152875180890189528681527f4d5463770000000000000000000000000000000000000000000000000000000081870152610220880152875180890189528681527f4d5467770000000000000000000000000000000000000000000000000000000081870152610240880152875180890189528681527f4d546b770000000000000000000000000000000000000000000000000000000081870152610260880152875180890189528681527f4d6a41770000000000000000000000000000000000000000000000000000000081870152610280880152875180890189528681527f4d6a457700000000000000000000000000000000000000000000000000000000818701526102a0880152875180890189528681527f4d6a497700000000000000000000000000000000000000000000000000000000818701526102c0880152875180890189528681527f4d6a4d7700000000000000000000000000000000000000000000000000000000818701526102e0880152875180890189528681527f4d6a51770000000000000000000000000000000000000000000000000000000081870152610300880152875180890189528681527f4d6a55770000000000000000000000000000000000000000000000000000000081870152610320880152875180890189528681527f4d6a59770000000000000000000000000000000000000000000000000000000081870152610340880152875180890189528681527f4d6a63770000000000000000000000000000000000000000000000000000000081870152610360880152875180890189528681527f4d6a67770000000000000000000000000000000000000000000000000000000081870152610380880152875180890189528681527f4d6a6b7700000000000000000000000000000000000000000000000000000000818701526103a0880152875180890189528681527f4d7a417700000000000000000000000000000000000000000000000000000000818701526103c0880152875180890189529586527f4d7a457700000000000000000000000000000000000000000000000000000000868601526103e08701959095528651948501875260008086529385019390935294830181905282810181905293820184905281019290925290610bbd60405180610100016040528060608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b610bc56132cb565b610bcd6132a4565b60008060205b6101a081101561115f57610bee8c8260008e8e60ff166124c9565b6040880152610c048c8260018e60ff8f166124c9565b6060880152610c1a8c8260028e60ff8f166124c9565b6080880152610c308c8260038e60ff8f166124c9565b60a0880152610c3f8888612663565b865286516004908890610c539083906147ad565b60ff908116909152610c7091508d9083906004908f908f166124c9565b6040880152610c868c8260058e60ff8f166124c9565b6060880152610c9c8c8260068e60ff8f166124c9565b6080880152610cb28c8260078e60ff8f166124c9565b60a0880152610cc18888612663565b602087015286516004908890610cd89083906147ad565b60ff16905250610ce960038261479a565b9050610cfc8c8260008e8e60ff166124c9565b6040880152610d128c8260018e60ff8f166124c9565b6060880152610d288c8260028e60ff8f166124c9565b6080880152610d3e8c8260038e60ff8f166124c9565b60a0880152610d4d8888612663565b604087015286516004908890610d649083906147ad565b60ff908116909152610d8191508d9083906004908f908f166124c9565b6040880152610d978c8260058e60ff8f166124c9565b6060880152610dad8c8260068e60ff8f166124c9565b6080880152610dc38c8260078e60ff8f166124c9565b60a0880152610dd28888612663565b606087015286516004908890610de99083906147ad565b60ff16905250610dfa60038261479a565b9050610e0d8c8260008e8e60ff166124c9565b6040880152610e238c8260018e60ff8f166124c9565b6060880152610e398c8260028e60ff8f166124c9565b6080880152610e4f8c8260038e60ff8f166124c9565b60a0880152610e5e8888612663565b608087015286516004908890610e759083906147ad565b60ff908116909152610e9291508d9083906004908f908f166124c9565b6040880152610ea88c8260058e60ff8f166124c9565b6060880152610ebe8c8260068e60ff8f166124c9565b6080880152610ed48c8260078e60ff8f166124c9565b60a0880152610ee38888612663565b60a087015286516004908890610efa9083906147ad565b60ff16905250610f0b60038261479a565b9050610f1e8c8260008e8e60ff166124c9565b6040880152610f348c8260018e60ff8f166124c9565b6060880152610f4a8c8260028e60ff8f166124c9565b6080880152610f608c8260038e60ff8f166124c9565b60a0880152610f6f8888612663565b60c087015286516004908890610f869083906147ad565b60ff908116909152610fa391508d9083906004908f908f166124c9565b6040880152610fb98c8260058e60ff8f166124c9565b6060880152610fcf8c8260068e60ff8f166124c9565b6080880152610fe58c8260078e60ff8f166124c9565b60a0880152610ff48888612663565b60e08701528651600490889061100b9083906147ad565b60ff1690525061101c60038261479a565b9050856000015186602001518760400151886060015189608001518a60a001518b60c001518c60e0015160405160200161105d989796959493929190613ea5565b6040516020818303038152906040528584806110789061497f565b955060ff166008811061109b57634e487b7160e01b600052603260045260246000fd5b602090810291909101919091526000885287018051600191906110bf9083906147ad565b60ff908116909152600890851610905061115a57845160208087015160408089015160608a015160808b015160a08c015160c08d015160e08e015195516111129998959694959394929391929101613ea5565b60405160208183030381529060405284838061112d9061497f565b945060ff166004811061115057634e487b7160e01b600052603260045260246000fd5b6020020152600092505b610bd3565b509196505050505050505b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146111b15760405162461bcd60e51b81526004016111a8906145d4565b60405180910390fd5b6111bb6000612826565b565b6000806000805b60105460ff821610156112a0576010805460ff83169081106111f657634e487b7160e01b600052603260045260246000fd5b90600052602060002090601091828204019190066002029054906101000a900461ffff1691508261ffff168561ffff16101580156112445750611239828461474a565b61ffff168561ffff16105b15611282578060ff166001141561126057506002949350505050565b600b8160ff16111561127757506001949350505050565b506000949350505050565b61128c828461474a565b9250806112988161497f565b9150506111c4565b50600080fd5b60606000806000806112b7866114b1565b935093509350935060006112cc858585610486565b8051602080830151604080850151606086015191519596506112f29592939092016143e4565b60405160208183030381529060405295505050505050919050565b606060008060008061132286600001516114b1565b9350935093509350606060005b8360ff168160ff16101561144457818251600014611382576040518060400160405280600481526020017f4c434237000000000000000000000000000000000000000000000000000000008152506113b9565b6040518060400160405280600481526020017f65794167000000000000000000000000000000000000000000000000000000008152505b848360ff16600d81106113dc57634e487b7160e01b600052603260045260246000fd5b6020020151888460ff16600d811061140457634e487b7160e01b600052603260045260246000fd5b6020020151600001516040516020016114209493929190613f10565b6040516020818303038152906040529150808061143c9061497f565b91505061132f565b506000611452868686610486565b805160208201516040830151606084015193945091929091908561147f61147a8f600661289b565b612adf565b60405160200161149496959493929190614159565b604051602081830303815290604052965050505050505092915050565b6114b96132e6565b6114c1613320565b60006114cb61334e565b60006114d686612ca8565b905060006114ea82600160200201516111bd565b60ff1690506000600f826003811061151257634e487b7160e01b600052603260045260246000fd5b600d020160070160078154811061153957634e487b7160e01b600052603260045260246000fd5b90600052602060002090601091828204019190066002029054906101000a900461ffff1661271061156a919061484e565b61ffff16836007602002015161ffff161090506000600f8361ffff16600381106115a457634e487b7160e01b600052603260045260246000fd5b600d02016008016007815481106115cb57634e487b7160e01b600052603260045260246000fd5b90600052602060002090601091828204019190066002029054906101000a900461ffff166127106115fc919061484e565b61ffff16846008602002015161ffff161090506000600f8461ffff166003811061163657634e487b7160e01b600052603260045260246000fd5b600d020160090160248154811061165d57634e487b7160e01b600052603260045260246000fd5b90600052602060002090601091828204019190066002029054906101000a900461ffff1661271061168e919061484e565b61ffff16856009602002015161ffff161090506000600f8561ffff16600381106116c857634e487b7160e01b600052603260045260246000fd5b600d0201600b016030815481106116ef57634e487b7160e01b600052603260045260246000fd5b90600052602060002090601091828204019190066002029054906101000a900461ffff16612710611720919061484e565b61ffff1686600b602002015161ffff161090506000806002888260200201516117499190614998565b61ffff1611905060005b600d8160ff161015611dbb57600060028260ff16600d811061178557634e487b7160e01b600052603260045260246000fd5b0160006117ba8b8560ff16600d81106117ae57634e487b7160e01b600052603260045260246000fd5b6020020151858c61217e565b81526020019081526020016000206040518060400160405290816000820180546117e3906148f5565b80601f016020809104026020016040519081016040528092919081815260200182805461180f906148f5565b801561185c5780601f106118315761010080835404028352916020019161185c565b820191906000526020600020905b81548152906001019060200180831161183f57829003601f168201915b50505050508152602001600182018054611875906148f5565b80601f01602080910402602001604051908101604052809291908181526020018280546118a1906148f5565b80156118ee5780601f106118c3576101008083540402835291602001916118ee565b820191906000526020600020905b8154815290600101906020018083116118d157829003601f168201915b505050505081525050905060008160200151511115611da7578160ff166002148061191c57508160ff16600c145b8015611926575085155b8015611930575086155b8061194757508160ff166007148015611947575085155b8061195e57508160ff16600a14801561195e575085155b806119b1575060028260ff161080611987575060028260ff16118015611987575060078260ff16105b8061199557508160ff166008145b806119a357508160ff166009145b806119b157508160ff16600b145b15611da7578480156119c05750835b80156119d757508160ff1660091480156119d75750825b806119ee57508160ff16600b1480156119ee575082155b156119f95750611da9565b808d8c60ff16600d8110611a1d57634e487b7160e01b600052603260045260246000fd5b6020020152611a568d60ff8d16600d8110611a4857634e487b7160e01b600052603260045260246000fd5b602002015160200151612d15565b8c8c60ff16600d8110611a7957634e487b7160e01b600052603260045260246000fd5b60209081029190910191909152604080516101e08101825260106101a082018181527f516d466a61326479623356755a434167000000000000000000000000000000006101c084015282528251808401845260088082527f556d466a5a5341670000000000000000000000000000000000000000000000008287015283860191909152835180850185528181527f526d466a5a5341670000000000000000000000000000000000000000000000008187015283850152835180850185528181527f5457393164476767000000000000000000000000000000000000000000000000818701526060840152835180850185528181527f546d397a5a534167000000000000000000000000000000000000000000000000818701526080840152835180850185528181527f52586c6c637941670000000000000000000000000000000000000000000000008187015260a08401528351808501855260148082527f525746794945466a5932567a63323979655341670000000000000000000000008288015260c0850191909152845180860186528181527f526d466a5a53424259324e6c63334e76636e6b670000000000000000000000008188015260e0850152845180860186529182527f5457467a6179416700000000000000000000000000000000000000000000000082870152610100840191909152835180850185528281527f534756685a4342435a577876647941670000000000000000000000000000000081870152610120840152835180850185528181527f52586c6c4945466a5932567a633239796553416700000000000000000000000081870152610140840152835180850185529182527f534756685a434242596d39325a5341670000000000000000000000000000000082860152610160830191909152825180840190935282527f545739316447676751574e6a5a584e7a62334a350000000000000000000000009282019290925261018082015260ff8316600d8110611d6c57634e487b7160e01b600052603260045260246000fd5b60200201518a8c60ff16600d8110611d9457634e487b7160e01b600052603260045260246000fd5b60200201528a611da38161497f565b9b50505b505b80611db38161497f565b915050611753565b50505050505050509193509193565b600060098260ff1611611deb57611de28260306147ad565b60f81b92915050565b8160ff16600a11158015611e035750600f8260ff1611155b1561013657600a611e158360616147ad565b611de29190614877565b60606000611e2c83612320565b9050805160021415611e605780604051602001611e49919061452d565b604051602081830303815290604052915050919050565b805160031415611e7b5780604051602001611e49919061412d565b805160041415611e965780604051602001611e499190614501565b8051600514156102fc5780604051602001611e499190613f7a565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ee85760405162461bcd60e51b81526004016111a8906145d4565b60005b61ffff811682111561210357604051806040016040528084848461ffff16818110611f2657634e487b7160e01b600052603260045260246000fd5b9050602002810190611f3891906146a4565b611f42908061463b565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001848461ffff8516818110611fa057634e487b7160e01b600052603260045260246000fd5b9050602002810190611fb291906146a4565b611fc090602081019061463b565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509152506002848461ffff851681811061201c57634e487b7160e01b600052603260045260246000fd5b905060200281019061202e91906146a4565b61203f9060608101906040016139cf565b60ff16600d811061206057634e487b7160e01b600052603260045260246000fd5b01600085858561ffff1681811061208757634e487b7160e01b600052603260045260246000fd5b905060200281019061209991906146a4565b6120aa9060808101906060016139cf565b60ff1681526020808201929092526040016000208251805191926120d392849290910190613369565b5060208281015180516120ec9260018501920190613369565b5090505080806120fb90614949565b915050611eeb565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461213f5760405162461bcd60e51b81526004016111a8906145d4565b73ffffffffffffffffffffffffffffffffffffffff81166121725760405162461bcd60e51b81526004016111a8906145c4565b61217b81612826565b50565b6000806000805b600f8561ffff16600381106121aa57634e487b7160e01b600052603260045260246000fd5b600d02018660ff16600d81106121d057634e487b7160e01b600052603260045260246000fd5b015460ff821610156122c857600f8561ffff166003811061220157634e487b7160e01b600052603260045260246000fd5b600d02018660ff16600d811061222757634e487b7160e01b600052603260045260246000fd5b018160ff168154811061224a57634e487b7160e01b600052603260045260246000fd5b90600052602060002090601091828204019190066002029054906101000a900461ffff1691508261ffff168761ffff1610158015612298575061228d828461474a565b61ffff168761ffff16105b156122aa5760ff16925061116a915050565b6122b4828461474a565b9250806122c08161497f565b915050612185565b50600f8461ffff16600381106122ee57634e487b7160e01b600052603260045260246000fd5b600d02018560ff16600d811061231457634e487b7160e01b600052603260045260246000fd5b01549695505050505050565b60606000825b801561234c57816123368161496b565b925061234590506010826147ce565b9050612326565b60008267ffffffffffffffff81111561237557634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561239f576020820181803683370190505b50905060005b83811015612444576123b86010876149b8565b92506123c383611dca565b8260016123d08488614871565b6123da9190614871565b815181106123f857634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506124326010876147ce565b955061243d8161496b565b90506123a5565b508051819061248b57505060408051808201909152600281527f30300000000000000000000000000000000000000000000000000000000000006020820152949350505050565b8051600114156124c057806040516020016124a69190613f7a565b604051602081830303815290604052945050505050919050565b95945050505050565b606060006124d8600184614871565b90505b60008482600d81106124fd57634e487b7160e01b600052603260045260246000fd5b60200201516125358984600d811061252557634e487b7160e01b600052603260045260246000fd5b6020020151602001518989612f73565b60ff166008811061255657634e487b7160e01b600052603260045260246000fd5b602002015190508060200151600014156125705750612651565b806020015160ff1415612587575191506124c09050565b6000612594600184614871565b90505b60008682600d81106125b957634e487b7160e01b600052603260045260246000fd5b60200201516125f18b84600d81106125e157634e487b7160e01b600052603260045260246000fd5b6020020151602001518b8b612f73565b60ff166008811061261257634e487b7160e01b600052603260045260246000fd5b6020020151905060008160200151111561263e5761263361147a84836131b7565b9450505050506124c0565b5080612649816148de565b915050612597565b8061265b816148de565b9150506124db565b6060816040015183836000015160ff166020811061269157634e487b7160e01b600052603260045260246000fd5b602002015184846020015160ff16602081106126bd57634e487b7160e01b600052603260045260246000fd5b60200201516060850151855187906126d69060016147ad565b60ff16602081106126f757634e487b7160e01b600052603260045260246000fd5b602002015187876020015160ff166020811061272357634e487b7160e01b600052603260045260246000fd5b6020020151608088015188518a9061273c9060026147ad565b60ff166020811061275d57634e487b7160e01b600052603260045260246000fd5b60200201518a8a6020015160ff166020811061278957634e487b7160e01b600052603260045260246000fd5b602002015160a08b01518b518d906127a29060036147ad565b60ff16602081106127c357634e487b7160e01b600052603260045260246000fd5b60200201518d8d6020015160ff16602081106127ef57634e487b7160e01b600052603260045260246000fd5b602002015160405160200161280f9c9b9a99989796959493929190613fae565b604051602081830303815290604052905092915050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60608260005b81156128c757806128b18161496b565b91506128c09050600a836147ce565b91506128a1565b60008467ffffffffffffffff8111156128f057634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561291a576020820181803683370190505b5085935090508561299b577f30000000000000000000000000000000000000000000000000000000000000008160008151811061296757634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600191505b81831115612a25576129ae600184614871565b92507f20000000000000000000000000000000000000000000000000000000000000008184815181106129f157634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061299b565b815b8615612ad557612a38600182614871565b90506000612a47600a896147ce565b612a5290600a61480f565b612a5c9089614871565b612a679060306147ad565b905060008160f81b905080848481518110612a9257634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612acc600a8a6147ce565b98505050612a27565b5095945050505050565b805160609080612aff575050604080516020810190915260008152919050565b60006003612b0e83600261479a565b612b1891906147ce565b612b2390600461480f565b90506000612b3282602061479a565b67ffffffffffffffff811115612b5857634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612b82576020820181803683370190505b5090506000604051806060016040528060408152602001614a79604091399050600181016020830160005b86811015612c0e576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101612bad565b506003860660018114612c285760028114612c7257612c9a565b7f3d3d0000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe830152612c9a565b7f3d000000000000000000000000000000000000000000000000000000000000006000198301525b505050918152949350505050565b612cb06133ed565b60005b600d811015612d0f57612cc8612710846149b8565b8282600d8110612ce857634e487b7160e01b600052603260045260246000fd5b61ffff9092166020929092020152600e9290921c9180612d078161496b565b915050612cb3565b50919050565b612d1d61340c565b612d2561340c565b60005b60088161ffff161015612f6c57612def612d9585612d478460046147e2565b61ffff1681518110612d6957634e487b7160e01b600052603260045260246000fd5b01602001517fff00000000000000000000000000000000000000000000000000000000000000166102ed565b612daf86612da48560046147e2565b612d4790600161474a565b612dc987612dbe8660046147e2565b612d4790600261474a565b604051602001612ddb93929190613e83565b604051602081830303815290604052612adf565b828261ffff1660088110612e1357634e487b7160e01b600052603260045260246000fd5b602002015152612e5584612e288360046147e2565b61ffff1681518110612e4a57634e487b7160e01b600052603260045260246000fd5b016020015160f81c90565b828261ffff1660088110612e7957634e487b7160e01b600052603260045260246000fd5b602002015160400152612e9c84612e918360046147e2565b612e2890600161474a565b828261ffff1660088110612ec057634e487b7160e01b600052603260045260246000fd5b602002015160600152612ee384612ed88360046147e2565b612e2890600261474a565b828261ffff1660088110612f0757634e487b7160e01b600052603260045260246000fd5b602002015160800152612f2a84612f1f8360046147e2565b612e2890600361474a565b828261ffff1660088110612f4e57634e487b7160e01b600052603260045260246000fd5b60209081029190910151015280612f6481614949565b915050612d28565b5092915050565b600081612fad576005848481518110612f9c57634e487b7160e01b600052603260045260246000fd5b016020015160f81c901c905061116a565b8160011415612ff85760086002858581518110612fda57634e487b7160e01b600052603260045260246000fd5b0160200151612ff1929160f89190911c901c6149be565b905061116a565b81600214156130895760078461300f85600161479a565b8151811061302d57634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b60f81c60ff16901c600485858151811061306257634e487b7160e01b600052603260045260246000fd5b0160200151613074919060f81c6149be565b61307f906002614829565b612ff191906147ad565b81600314156130c05760086004856130a286600161479a565b81518110612fda57634e487b7160e01b600052603260045260246000fd5b81600414156130d85760086001856130a2868361479a565b8160051415613160576006846130ef85600261479a565b8151811061310d57634e487b7160e01b600052603260045260246000fd5b016020015160f81c901c60028561312586600161479a565b8151811061314357634e487b7160e01b600052603260045260246000fd5b0160200151613155919060f81c6149be565b61307f906004614829565b81600614156131795760086003856130a286600261479a565b60088461318785600261479a565b815181106131a557634e487b7160e01b600052603260045260246000fd5b0160200151612ff1919060f81c6149be565b60606000836020015160016131cc919061479a565b61ffff169050600084602001516101006131e69190614871565b61ffff1690506124c060106008866040015184613203919061480f565b6040890151613212908761480f565b61321c919061479a565b901c62ffffff16901b600880876060015185613238919061480f565b60608a0151613247908861480f565b613251919061479a565b901c62ffffff16901b600887608001518561326c919061480f565b60808a015161327b908861480f565b613285919061479a565b61329092911c614773565b61329a9190614773565b62ffffff16611e1f565b60405180608001604052806004905b60608152602001906001900390816132b35790505090565b604080516101008101909152606081526007602082016132b3565b604051806101a00160405280600d905b60408051808201909152606080825260208201528152602001906001900390816132f65790505090565b604051806101a00160405280600d905b61333861340c565b8152602001906001900390816133305790505090565b604080516101a0810190915260608152600c602082016132b3565b828054613375906148f5565b90600052602060002090601f01602090048101928261339757600085556133dd565b82601f106133b057805160ff19168380011785556133dd565b828001600101855582156133dd579182015b828111156133dd5782518255916020019190600101906133c2565b506133e9929150613464565b5090565b604051806101a00160405280600d906020820280368337509192915050565b6040518061010001604052806008905b61344e6040518060a0016040528060608152602001600081526020016000815260200160008152602001600081525090565b81526020019060019003908161341c5790505090565b5b808211156133e95760008155600101613465565b600061348c613487846146fe565b6146e2565b905080828560208602850111156134a257600080fd5b60005b858110156134e657813567ffffffffffffffff8111156134c457600080fd5b85016134d08882613629565b84525060209283019291909101906001016134a5565b5050509392505050565b60006134fe613487846146fe565b9050808285602086028501111561351457600080fd5b60005b858110156134e657813567ffffffffffffffff81111561353657600080fd5b85016135428882613708565b8452506020928301929190910190600101613517565b6000613566613487846146fe565b9050808285602086028501111561357c57600080fd5b60005b858110156134e657813567ffffffffffffffff81111561359e57600080fd5b85016135aa888261378f565b845250602092830192919091019060010161357f565b60006135ce6134878461471f565b9050828152602081018484840111156135e657600080fd5b6135f18482856148a2565b509392505050565b80356102fc81614a23565b600082601f830112613614578081fd5b600d613621848285613479565b949350505050565b600082601f830112613639578081fd5b60086136218482856134f0565b60008083601f840112613657578182fd5b50813567ffffffffffffffff81111561366e578182fd5b60208301915083602082028301111561368657600080fd5b9250929050565b600082601f83011261369d578081fd5b600d613621848285613558565b80356102fc81614a37565b600082601f8301126136c5578081fd5b81356136218482602086016135c0565b6000602082840312156136e6578081fd5b6136f060206146e2565b905060006136fe848461380f565b9082015292915050565b600060a08284031215613719578081fd5b61372360a06146e2565b9050813567ffffffffffffffff81111561373c57600080fd5b613748848285016136b5565b82525060206137598484830161380f565b90820152604061376b8484830161380f565b90820152606061377d8484830161380f565b9082015260806136fe8484830161380f565b6000604082840312156137a0578081fd5b6137aa60406146e2565b9050813567ffffffffffffffff8111156137c357600080fd5b6137cf848285016136b5565b825250602082013567ffffffffffffffff8111156137ec57600080fd5b6137f8848285016136b5565b60208301525092915050565b80356102fc81614a5f565b80356102fc81614a69565b80356102fc81614a6f565b600060208284031215613836578081fd5b61116a838284016135f9565b60008060208385031215613854578081fd5b8083013567ffffffffffffffff81111561386c578182fd5b61387885828601613646565b92509250509250929050565b600080600060608486031215613898578081fd5b8084013567ffffffffffffffff8111156138b0578182fd5b6138bc8682870161368d565b935050602084013567ffffffffffffffff8111156138d8578182fd5b6138e486828701613604565b92505060406138f58682870161381a565b9150509250925092565b600060208284031215613910578081fd5b61116a838284016136aa565b60006020828403121561392d578081fd5b61116a83828401613804565b60008060006060848603121561394d578081fd5b61395985828601613804565b925060206139698682870161381a565b92505060406138f586828701613804565b60006020828403121561398b578081fd5b61116a8382840161380f565b600080604083850312156139a9578182fd5b6139b58483850161380f565b915060206139c5858286016136d5565b9150509250929050565b6000602082840312156139e0578081fd5b61116a8382840161381a565b600080604083850312156139fe578182fd5b613a0a8483850161381a565b915060206139c58582860161381a565b600061116a8383613b1e565b600061116a8383613bc2565b600061116a8383613ddc565b600061116a8383613e42565b613a5381614884565b82525050565b6000600d836101a0810184845b84811015613a975783830388528151613a7f8482613a1a565b93505060208201602098909801979150600101613a66565b50909695505050505050565b6000600d836101a0810184845b84811015613a975783830388528151613ac98482613a26565b93505060208201602098909801979150600101613ab0565b60006004836080810184845b84811015613a975783830388528151613b068482613a26565b93505060208201602098909801979150600101613aed565b6000600883610100810184845b84811015613a975783830388528151613b448482613a32565b93505060208201602098909801979150600101613b2b565b6000600d836101a0810184845b84811015613a975783830388528151613b828482613a3e565b93505060208201602098909801979150600101613b69565b7fff000000000000000000000000000000000000000000000000000000000000008116613a53565b6000613bcc825190565b808452602084019350613be38185602086016148ae565b601f01601f19169290920192915050565b6000613bfe825190565b613c0c8185602086016148ae565b9290920192915050565b7f496e527959576c3058335235634755694f69416900000000000000000000000081525b60140190565b7f50484a6c593351674943426d615778735053636a0000000000000000000000008152613c3a565b60268152602081017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181527f6464726573730000000000000000000000000000000000000000000000000000602082015290505b60400190565b7f4a7941676544306e00000000000000000000000000000000000000000000000081525b60080190565b7f4a7941674943382b0000000000000000000000000000000000000000000000008152613ce6565b7f50484e306557786c506e4a6c5933523764326c6b644767364d5842344f32686c81527f6157646f64446f786348673766547776633352356247552b5043397a646d632b6020820152613cbc565b7f496942390000000000000000000000000000000000000000000000000000000081525b60040190565b7f4a7941676554306e0000000000000000000000000000000000000000000000008152613ce6565b7f30303030000000000000000000000000000000000000000000000000000000008152613d86565b805160a080845260009190840190613df48282613bc2565b9150506020830151613e096020860182613e74565b506040830151613e1c6040860182613e74565b506060830151613e2f6060860182613e74565b5060808301516135f16080860182613e74565b8051604080845260009190840190613e5a8282613bc2565b915050602083015184820360208601526124c08282613bc2565b80613a53565b60ff8116613a53565b613e8d8185613bf4565b9050613e998184613bf4565b90506136218183613bf4565b613eaf818a613bf4565b9050613ebb8189613bf4565b9050613ec78188613bf4565b9050613ed38187613bf4565b9050613edf8186613bf4565b9050613eeb8185613bf4565b9050613ef78184613bf4565b9050613f038183613bf4565b9998505050505050505050565b613f1a8186613bf4565b9050613f268185613bf4565b9050613f3181613c16565b9050613f3d8184613bf4565b7f49697769646d4673645755694f6941690000000000000000000000000000000081526010019050613f6f8183613bf4565b90506124c081613d62565b7f30000000000000000000000000000000000000000000000000000000000000008152600181015b90506102fc8183613bf4565b613fb781613c40565b9050613fc3818e613bf4565b9050613fce81613cc2565b9050613fda818d613bf4565b9050613fe581613d8c565b9050613ff1818c613bf4565b7f4a794176506a78795a574e304943426d615778735053636a000000000000000081526018019050614023818b613bf4565b905061402e81613cc2565b905061403a818a613bf4565b905061404581613d8c565b90506140518189613bf4565b7f4a794176506a78795a574e304943426d615778735053636a0000000000000000815260180190506140838188613bf4565b905061408e81613cc2565b905061409a8187613bf4565b90506140a581613d8c565b90506140b18186613bf4565b7f4a794176506a78795a574e304943426d615778735053636a0000000000000000815260180190506140e38185613bf4565b90506140ee81613cc2565b90506140fa8184613bf4565b905061410581613d8c565b90506141118183613bf4565b905061411c81613cec565b9d9c50505050505050505050505050565b7f3030300000000000000000000000000000000000000000000000000000000000815260038101613fa2565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c65794181527f67496d6c745957646c58325268644745694f69416950484e325a7942325a584a60208201527f7a61573975505363784c6a456e49485a705a586443623367394a7a41674d434160408201527f7a4d6a41674d7a49774a79423462577875637a306e6148523063446f764c336460608201527f33647935334d793576636d63764d6a41774d43397a646d636e49484e6f59584260808201527f6c4c584a6c626d526c636d6c755a7a306e59334a70633342465a47646c63796360a08201527f2b0000000000000000000000000000000000000000000000000000000000000060c082015260c10161426d8188613bf4565b90506142798187613bf4565b90506142858186613bf4565b90506142918185613bf4565b7f50484e306557786c506e4a6c5933523764326c6b644767364d5442776544746f81527f5a576c6e614851364d544277654474395043397a64486c735a5434384c334e3260208201527f5a7a346749697767496d463064484a70596e56305a584d694f694262000000006040820152605c01905061430f8184613bf4565b7f5853776749434169626d46745a534936496c4a31626d356c6369416a000000008152601c0190506143418183613bf4565b7f49697767496d526c63324e796158423061573975496a6f67496b4e6f59576c7581527f49464a31626d356c636e4d6759584a6c4945316c5a32456751326c306553427960208201527f5a57356c5a32466b5a584d674d5441774a53426e5a57356c636d46305a57516760408201527f623234675932686861573475496e3067000000000000000000000000000000006060820152607001979650505050505050565b7f50484e325a7942325a584a7a61573975505363784c6a456e49485a705a58644381527f623367394a7a41674d43417a4d69417a4d69636765473173626e4d394a32683060208201527f644841364c79393364336375647a4d7562334a6e4c7a49774d44417663335a6e60408201527f4a79427a614746775a5331795a57356b5a584a70626d63394a324e7961584e7760608201527f5257526e5a584d6e4947686c6157646f6444306e4d5441774a53636764326c6b60808201527f644767394a7a45774d43556e4943412b0000000000000000000000000000000060a082015260b0016144d28186613bf4565b90506144de8185613bf4565b90506144ea8184613bf4565b90506144f68183613bf4565b90506124c081613d14565b7f3030000000000000000000000000000000000000000000000000000000000000815260028101613fa2565b613fa281613db4565b602081016102fc8284613a4a565b6020808252810161116a8184613ae1565b608080825281016145668187613b5c565b9050818103602083015261457a8186613a59565b90506145896040830185613e7a565b818103606083015261459b8184613aa3565b9695505050505050565b602081016102fc8284613b9a565b6020808252810161116a8184613bc2565b602080825281016102fc81613c68565b60208082528181019081527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726040830152606082016102fc565b6020808252810161116a8184613e42565b602081016102fc8284613e74565b602081016102fc8284613e7a565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe136859003018112614670578283fd5b8301915050803567ffffffffffffffff81111561468c57600080fd5b60208201915060018102360382131561368657600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81368490030181126146d8578182fd5b9190910192915050565b60006146ed60405190565b90506146f9828261491c565b919050565b600067ffffffffffffffff82111561471857614718614a0d565b5060200290565b600067ffffffffffffffff82111561473957614739614a0d565b601f19601f83011660200192915050565b61ffff8116905061ffff8216915060008261ffff0382111561476e5761476e6149cb565b500190565b62ffffff8116905062ffffff8216915060008262ffffff0382111561476e5761476e6149cb565b6000821982111561476e5761476e6149cb565b60ff8116905060ff8216915060008260ff0382111561476e5761476e6149cb565b6000826147dd576147dd6149e1565b500490565b61ffff8116905061ffff8216915060008161ffff048311821515161561480a5761480a6149cb565b500290565b600081600019048311821515161561480a5761480a6149cb565b60ff8116905060ff8216915060008160ff048311821515161561480a5761480a6149cb565b61ffff9081169082165b915060008282101561486c5761486c6149cb565b500390565b81614858565b60ff908116908216614858565b600073ffffffffffffffffffffffffffffffffffffffff82166102fc565b82818337506000910152565b60005b838110156148c95781810151838201526020016148b1565b838111156148d8576000848401525b50505050565b6000816148ed576148ed6149cb565b506000190190565b60028104600182168061490957607f821691505b60208210811415612d0f57612d0f6149f7565b601f19601f830116810181811067ffffffffffffffff8211171561494257614942614a0d565b6040525050565b61ffff81169050600061ffff821415614964576149646149cb565b5060010190565b6000600019821415614964576149646149cb565b60ff81169050600060ff821415614964576149646149cb565b61ffff9081169082165b91506000826149b3576149b36149e1565b500690565b816149a2565b60ff9081169082166149a2565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b614a2c81614884565b811461217b57600080fd5b7fff000000000000000000000000000000000000000000000000000000000000008116614a2c565b61ffff8116614a2c565b80614a2c565b60ff8116614a2c56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa2646970667358221220f79b71ac4225048790188e56417d5caf616a369991325cac1d61ad35ff50bc2864736f6c63430008040033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

Validator Index Block Amount
View All Withdrawals
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.