ETH Price: $3,415.66 (+4.83%)

Token

combine. (c)
 

Overview

Max Total Supply

197 c

Holders

197

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
idonotknowwhatimdoing.eth
Balance
1 c
0xbaaba861464f25f52c2ee10cc3ac024f4f77812a
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Combine

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-12-31
*/

// SPDX-License-Identifier: MIT
// File: Strings.sol



pragma solidity ^0.8.6;

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

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

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

}
// File: Roots.sol



pragma solidity ^0.8.6;

library Roots {

// calculates a^(1/n) to dp decimal places
    // maxIts bounds the number of iterations performed
    function nthRoot(uint _a, uint _n, uint _dp, uint _maxIts) pure internal returns(uint) {
        assert (_n > 1);

        // The scale factor is a crude way to turn everything into integer calcs.
        // Actually do (a * (10 ^ ((dp + 1) * n))) ^ (1/n)
        // We calculate to one extra dp and round at the end
        uint one = 10 ** (1 + _dp);
        uint a0 = one ** _n * _a;

        // Initial guess: 1.0
        uint xNew = one;

        uint iter = 0;
        while (iter < _maxIts) {
            uint x = xNew;
            uint t0 = x ** (_n - 1);
            if (x * t0 > a0) {
                xNew = x - (x - a0 / t0) / _n;
            } else {
                xNew = x + (a0 / t0 - x) / _n;
            }
            ++iter;
            if(xNew == x) {
                break;
            }
        }

        // Round to nearest in the last dp.
        return (xNew + 5) / 10;
    }
}
// File: Base64.sol



pragma solidity >=0.6.0;

/// @title Base64
/// @author Brecht Devos - <[email protected]>
/// @notice Provides functions for encoding/decoding base64
library Base64 {
    string internal constant TABLE_ENCODE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    bytes  internal constant TABLE_DECODE = hex"0000000000000000000000000000000000000000000000000000000000000000"
                                            hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
                                            hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
                                            hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";

    function encode(bytes memory data) internal pure returns (string memory) {
        if (data.length == 0) return '';

        // load the table into memory
        string memory table = TABLE_ENCODE;

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

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {}
            {
                // read 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // write 4 characters
                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F))))
                resultPtr := add(resultPtr, 1)
                mstore8(resultPtr, mload(add(tablePtr, and(        input,  0x3F))))
                resultPtr := add(resultPtr, 1)
            }

            // padding with '='
            switch mod(mload(data), 3)
            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
        }

        return result;
    }

    function decode(string memory _data) internal pure returns (bytes memory) {
        bytes memory data = bytes(_data);

        if (data.length == 0) return new bytes(0);
        require(data.length % 4 == 0, "invalid base64 decoder input");

        // load the table into memory
        bytes memory table = TABLE_DECODE;

        // every 4 characters represent 3 bytes
        uint256 decodedLen = (data.length / 4) * 3;

        // add some extra buffer at the end required for the writing
        bytes memory result = new bytes(decodedLen + 32);

        assembly {
            // padding with '='
            let lastBytes := mload(add(data, mload(data)))
            if eq(and(lastBytes, 0xFF), 0x3d) {
                decodedLen := sub(decodedLen, 1)
                if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
                    decodedLen := sub(decodedLen, 1)
                }
            }

            // set the actual output length
            mstore(result, decodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 4 characters at a time
            for {} lt(dataPtr, endPtr) {}
            {
               // read 4 characters
               dataPtr := add(dataPtr, 4)
               let input := mload(dataPtr)

               // write 3 bytes
               let output := add(
                   add(
                       shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)),
                       shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))),
                   add(
                       shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)),
                               and(mload(add(tablePtr, and(        input , 0xFF))), 0xFF)
                    )
                )
                mstore(resultPtr, shl(232, output))
                resultPtr := add(resultPtr, 3)
            }
        }

        return result;
    }
}
// File: ABDKMath64x64.sol


/*
 * ABDK Math 64.64 Smart Contract Library.  Copyright © 2019 by ABDK Consulting.
 * Author: Mikhail Vladimirov <[email protected]>
 */
pragma solidity ^0.8.6;

/**
 * Smart contract library of mathematical functions operating with signed
 * 64.64-bit fixed point numbers.  Signed 64.64-bit fixed point number is
 * basically a simple fraction whose numerator is signed 128-bit integer and
 * denominator is 2^64.  As long as denominator is always the same, there is no
 * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are
 * represented by int128 type holding only the numerator.
 */
library ABDKMath64x64 {
  /*
   * Minimum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;

  /*
   * Maximum value signed 64.64-bit fixed point number may have. 
   */
  int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

  /**
   * Convert signed 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromInt (int256 x) internal pure returns (int128) {
    unchecked {
      require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
      return int128 (x << 64);
    }
  }

  /**
   * Convert signed 64.64 fixed point number into signed 64-bit integer number
   * rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64-bit integer number
   */
  function toInt (int128 x) internal pure returns (int64) {
    unchecked {
      return int64 (x >> 64);
    }
  }

  /**
   * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point
   * number.  Revert on overflow.
   *
   * @param x unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function fromUInt (uint256 x) internal pure returns (int128) {
    unchecked {
      require (x <= 0x7FFFFFFFFFFFFFFF);
      return int128 (int256 (x << 64));
    }
  }

  /**
   * Convert signed 64.64 fixed point number into unsigned 64-bit integer
   * number rounding down.  Revert on underflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return unsigned 64-bit integer number
   */
  function toUInt (int128 x) internal pure returns (uint64) {
    unchecked {
      require (x >= 0);
      return uint64 (uint128 (x >> 64));
    }
  }

  /**
   * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point
   * number rounding down.  Revert on overflow.
   *
   * @param x signed 128.128-bin fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function from128x128 (int256 x) internal pure returns (int128) {
    unchecked {
      int256 result = x >> 64;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Convert signed 64.64 fixed point number into signed 128.128 fixed point
   * number.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 128.128 fixed point number
   */
  function to128x128 (int128 x) internal pure returns (int256) {
    unchecked {
      return int256 (x) << 64;
    }
  }

  /**
   * Calculate x + y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function add (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) + y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x - y.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sub (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) - y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x * y rounding down.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function mul (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 result = int256(x) * y >> 64;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point
   * number and y is signed 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y signed 256-bit integer number
   * @return signed 256-bit integer number
   */
  function muli (int128 x, int256 y) internal pure returns (int256) {
    unchecked {
      if (x == MIN_64x64) {
        require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
          y <= 0x1000000000000000000000000000000000000000000000000);
        return -y << 63;
      } else {
        bool negativeResult = false;
        if (x < 0) {
          x = -x;
          negativeResult = true;
        }
        if (y < 0) {
          y = -y; // We rely on overflow behavior here
          negativeResult = !negativeResult;
        }
        uint256 absoluteResult = mulu (x, uint256 (y));
        if (negativeResult) {
          require (absoluteResult <=
            0x8000000000000000000000000000000000000000000000000000000000000000);
          return -int256 (absoluteResult); // We rely on overflow behavior here
        } else {
          require (absoluteResult <=
            0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
          return int256 (absoluteResult);
        }
      }
    }
  }

  /**
   * Calculate x * y rounding down, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64 fixed point number
   * @param y unsigned 256-bit integer number
   * @return unsigned 256-bit integer number
   */
  function mulu (int128 x, uint256 y) internal pure returns (uint256) {
    unchecked {
      if (y == 0) return 0;

      require (x >= 0);

      uint256 lo = (uint256 (int256 (x)) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
      uint256 hi = uint256 (int256 (x)) * (y >> 128);

      require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      hi <<= 64;

      require (hi <=
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo);
      return hi + lo;
    }
  }

  /**
   * Calculate x / y rounding towards zero.  Revert on overflow or when y is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function div (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);
      int256 result = (int256 (x) << 64) / y;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are signed 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x signed 256-bit integer number
   * @param y signed 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divi (int256 x, int256 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);

      bool negativeResult = false;
      if (x < 0) {
        x = -x; // We rely on overflow behavior here
        negativeResult = true;
      }
      if (y < 0) {
        y = -y; // We rely on overflow behavior here
        negativeResult = !negativeResult;
      }
      uint128 absoluteResult = divuu (uint256 (x), uint256 (y));
      if (negativeResult) {
        require (absoluteResult <= 0x80000000000000000000000000000000);
        return -int128 (absoluteResult); // We rely on overflow behavior here
      } else {
        require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int128 (absoluteResult); // We rely on overflow behavior here
      }
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return signed 64.64-bit fixed point number
   */
  function divu (uint256 x, uint256 y) internal pure returns (int128) {
    unchecked {
      require (y != 0);
      uint128 result = divuu (x, y);
      require (result <= uint128 (MAX_64x64));
      return int128 (result);
    }
  }

  /**
   * Calculate -x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function neg (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != MIN_64x64);
      return -x;
    }
  }

  /**
   * Calculate |x|.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function abs (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != MIN_64x64);
      return x < 0 ? -x : x;
    }
  }

  /**
   * Calculate 1 / x rounding towards zero.  Revert on overflow or when x is
   * zero.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function inv (int128 x) internal pure returns (int128) {
    unchecked {
      require (x != 0);
      int256 result = int256 (0x100000000000000000000000000000000) / x;
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function avg (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      return int128 ((int256 (x) + int256 (y)) >> 1);
    }
  }

  /**
   * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.
   * Revert on overflow or in case x * y is negative.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function gavg (int128 x, int128 y) internal pure returns (int128) {
    unchecked {
      int256 m = int256 (x) * int256 (y);
      require (m >= 0);
      require (m <
          0x4000000000000000000000000000000000000000000000000000000000000000);
      return int128 (sqrtu (uint256 (m)));
    }
  }

  /**
   * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number
   * and y is unsigned 256-bit integer number.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @param y uint256 value
   * @return signed 64.64-bit fixed point number
   */
  function pow (int128 x, uint256 y) internal pure returns (int128) {
    unchecked {
      bool negative = x < 0 && y & 1 == 1;

      uint256 absX = uint128 (x < 0 ? -x : x);
      uint256 absResult;
      absResult = 0x100000000000000000000000000000000;

      if (absX <= 0x10000000000000000) {
        absX <<= 63;
        while (y != 0) {
          if (y & 0x1 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x2 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x4 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          if (y & 0x8 != 0) {
            absResult = absResult * absX >> 127;
          }
          absX = absX * absX >> 127;

          y >>= 4;
        }

        absResult >>= 64;
      } else {
        uint256 absXShift = 63;
        if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; }
        if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; }
        if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; }
        if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; }
        if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; }
        if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; }

        uint256 resultShift = 0;
        while (y != 0) {
          require (absXShift < 64);

          if (y & 0x1 != 0) {
            absResult = absResult * absX >> 127;
            resultShift += absXShift;
            if (absResult > 0x100000000000000000000000000000000) {
              absResult >>= 1;
              resultShift += 1;
            }
          }
          absX = absX * absX >> 127;
          absXShift <<= 1;
          if (absX >= 0x100000000000000000000000000000000) {
              absX >>= 1;
              absXShift += 1;
          }

          y >>= 1;
        }

        require (resultShift < 64);
        absResult >>= 64 - resultShift;
      }
      int256 result = negative ? -int256 (absResult) : int256 (absResult);
      require (result >= MIN_64x64 && result <= MAX_64x64);
      return int128 (result);
    }
  }

  /**
   * Calculate sqrt (x) rounding down.  Revert if x < 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function sqrt (int128 x) internal pure returns (int128) {
    unchecked {
      require (x >= 0);
      return int128 (sqrtu (uint256 (int256 (x)) << 64));
    }
  }

  /**
   * Calculate binary logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function log_2 (int128 x) internal pure returns (int128) {
    unchecked {
      require (x > 0);

      int256 msb = 0;
      int256 xc = x;
      if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; }
      if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
      if (xc >= 0x10000) { xc >>= 16; msb += 16; }
      if (xc >= 0x100) { xc >>= 8; msb += 8; }
      if (xc >= 0x10) { xc >>= 4; msb += 4; }
      if (xc >= 0x4) { xc >>= 2; msb += 2; }
      if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

      int256 result = msb - 64 << 64;
      uint256 ux = uint256 (int256 (x)) << uint256 (127 - msb);
      for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
        ux *= ux;
        uint256 b = ux >> 255;
        ux >>= 127 + b;
        result += bit * int256 (b);
      }

      return int128 (result);
    }
  }

  /**
   * Calculate natural logarithm of x.  Revert if x <= 0.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function ln (int128 x) internal pure returns (int128) {
    unchecked {
      require (x > 0);

      return int128 (int256 (
          uint256 (int256 (log_2 (x))) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128));
    }
  }

  /**
   * Calculate binary exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp_2 (int128 x) internal pure returns (int128) {
    unchecked {
      require (x < 0x400000000000000000); // Overflow

      if (x < -0x400000000000000000) return 0; // Underflow

      uint256 result = 0x80000000000000000000000000000000;

      if (x & 0x8000000000000000 > 0)
        result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
      if (x & 0x4000000000000000 > 0)
        result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
      if (x & 0x2000000000000000 > 0)
        result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
      if (x & 0x1000000000000000 > 0)
        result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
      if (x & 0x800000000000000 > 0)
        result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
      if (x & 0x400000000000000 > 0)
        result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
      if (x & 0x200000000000000 > 0)
        result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
      if (x & 0x100000000000000 > 0)
        result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
      if (x & 0x80000000000000 > 0)
        result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
      if (x & 0x40000000000000 > 0)
        result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
      if (x & 0x20000000000000 > 0)
        result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
      if (x & 0x10000000000000 > 0)
        result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
      if (x & 0x8000000000000 > 0)
        result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
      if (x & 0x4000000000000 > 0)
        result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
      if (x & 0x2000000000000 > 0)
        result = result * 0x1000162E525EE054754457D5995292026 >> 128;
      if (x & 0x1000000000000 > 0)
        result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
      if (x & 0x800000000000 > 0)
        result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
      if (x & 0x400000000000 > 0)
        result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
      if (x & 0x200000000000 > 0)
        result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128;
      if (x & 0x100000000000 > 0)
        result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
      if (x & 0x80000000000 > 0)
        result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
      if (x & 0x40000000000 > 0)
        result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
      if (x & 0x20000000000 > 0)
        result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
      if (x & 0x10000000000 > 0)
        result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
      if (x & 0x8000000000 > 0)
        result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
      if (x & 0x4000000000 > 0)
        result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
      if (x & 0x2000000000 > 0)
        result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
      if (x & 0x1000000000 > 0)
        result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
      if (x & 0x800000000 > 0)
        result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
      if (x & 0x400000000 > 0)
        result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
      if (x & 0x200000000 > 0)
        result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
      if (x & 0x100000000 > 0)
        result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
      if (x & 0x80000000 > 0)
        result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
      if (x & 0x40000000 > 0)
        result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
      if (x & 0x20000000 > 0)
        result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128;
      if (x & 0x10000000 > 0)
        result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
      if (x & 0x8000000 > 0)
        result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
      if (x & 0x4000000 > 0)
        result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
      if (x & 0x2000000 > 0)
        result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
      if (x & 0x1000000 > 0)
        result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128;
      if (x & 0x800000 > 0)
        result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
      if (x & 0x400000 > 0)
        result = result * 0x100000000002C5C85FDF477B662B26945 >> 128;
      if (x & 0x200000 > 0)
        result = result * 0x10000000000162E42FEFA3AE53369388C >> 128;
      if (x & 0x100000 > 0)
        result = result * 0x100000000000B17217F7D1D351A389D40 >> 128;
      if (x & 0x80000 > 0)
        result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
      if (x & 0x40000 > 0)
        result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
      if (x & 0x20000 > 0)
        result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128;
      if (x & 0x10000 > 0)
        result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
      if (x & 0x8000 > 0)
        result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
      if (x & 0x4000 > 0)
        result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128;
      if (x & 0x2000 > 0)
        result = result * 0x1000000000000162E42FEFA39F02B772C >> 128;
      if (x & 0x1000 > 0)
        result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
      if (x & 0x800 > 0)
        result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
      if (x & 0x400 > 0)
        result = result * 0x100000000000002C5C85FDF473DEA871F >> 128;
      if (x & 0x200 > 0)
        result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128;
      if (x & 0x100 > 0)
        result = result * 0x100000000000000B17217F7D1CF79E949 >> 128;
      if (x & 0x80 > 0)
        result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
      if (x & 0x40 > 0)
        result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
      if (x & 0x20 > 0)
        result = result * 0x100000000000000162E42FEFA39EF366F >> 128;
      if (x & 0x10 > 0)
        result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128;
      if (x & 0x8 > 0)
        result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
      if (x & 0x4 > 0)
        result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
      if (x & 0x2 > 0)
        result = result * 0x1000000000000000162E42FEFA39EF358 >> 128;
      if (x & 0x1 > 0)
        result = result * 0x10000000000000000B17217F7D1CF79AB >> 128;

      result >>= uint256 (int256 (63 - (x >> 64)));
      require (result <= uint256 (int256 (MAX_64x64)));

      return int128 (int256 (result));
    }
  }

  /**
   * Calculate natural exponent of x.  Revert on overflow.
   *
   * @param x signed 64.64-bit fixed point number
   * @return signed 64.64-bit fixed point number
   */
  function exp (int128 x) internal pure returns (int128) {
    unchecked {
      require (x < 0x400000000000000000); // Overflow

      if (x < -0x400000000000000000) return 0; // Underflow

      return exp_2 (
          int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128));
    }
  }

  /**
   * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
   * integer numbers.  Revert on overflow or when y is zero.
   *
   * @param x unsigned 256-bit integer number
   * @param y unsigned 256-bit integer number
   * @return unsigned 64.64-bit fixed point number
   */
  function divuu (uint256 x, uint256 y) private pure returns (uint128) {
    unchecked {
      require (y != 0);

      uint256 result;

      if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
        result = (x << 64) / y;
      else {
        uint256 msb = 192;
        uint256 xc = x >> 192;
        if (xc >= 0x100000000) { xc >>= 32; msb += 32; }
        if (xc >= 0x10000) { xc >>= 16; msb += 16; }
        if (xc >= 0x100) { xc >>= 8; msb += 8; }
        if (xc >= 0x10) { xc >>= 4; msb += 4; }
        if (xc >= 0x4) { xc >>= 2; msb += 2; }
        if (xc >= 0x2) msb += 1;  // No need to shift xc anymore

        result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1);
        require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

        uint256 hi = result * (y >> 128);
        uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

        uint256 xh = x >> 192;
        uint256 xl = x << 64;

        if (xl < lo) xh -= 1;
        xl -= lo; // We rely on overflow behavior here
        lo = hi << 128;
        if (xl < lo) xh -= 1;
        xl -= lo; // We rely on overflow behavior here

        assert (xh == hi >> 128);

        result += xl / y;
      }

      require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
      return uint128 (result);
    }
  }

  /**
   * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer
   * number.
   *
   * @param x unsigned 256-bit integer number
   * @return unsigned 128-bit integer number
   */
  function sqrtu (uint256 x) private pure returns (uint128) {
    unchecked {
      if (x == 0) return 0;
      else {
        uint256 xx = x;
        uint256 r = 1;
        if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; }
        if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; }
        if (xx >= 0x100000000) { xx >>= 32; r <<= 16; }
        if (xx >= 0x10000) { xx >>= 16; r <<= 8; }
        if (xx >= 0x100) { xx >>= 8; r <<= 4; }
        if (xx >= 0x10) { xx >>= 4; r <<= 2; }
        if (xx >= 0x8) { r <<= 1; }
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1; // Seven iterations should be enough
        uint256 r1 = x / r;
        return uint128 (r < r1 ? r : r1);
      }
    }
  }
}
// File: CombineMetadata.sol


pragma solidity ^0.8.6;





interface ICombineMetadata {    
    function tokenMetadata(
        uint256 tokenId, 
        uint256 rarity, 
        uint256 tokenDensity, 
        uint256 alphaDensity, 
        bool isAlpha, 
        uint256 mergeCount) external view returns (string memory);
}

contract CombineMetadata is ICombineMetadata {
    
    struct ERC721MetadataStructure {
        bool isImageLinked;
        string name;
        string description;
        string createdBy;
        string image;
        ERC721MetadataAttribute[] attributes;
    }

    struct ERC721MetadataAttribute {
        bool includeDisplayType;
        bool includeTraitType;
        bool isValueAString;
        string displayType;
        string traitType;
        string value;
    }
    
    using ABDKMath64x64 for int128;    
    using Base64 for string;
    using Roots for uint;    
    using Strings for uint256;    
    
    address public owner;  

    string private _name;
    string private _imageBaseURI;
    string private _imageExtension;
    uint256 private _maxRadius;
    string[] private _imageParts;
    mapping (string => string) private _classStyles;
  
    string constant private _OFFSET_TAG = '<OFFSET>';
    string constant private _RADIUS_TAG = '<RADIUS>';
    string constant private _CLASS_TAG = '<CLASS>';  
    string constant private _CLASS_STYLE_TAG = '<CLASS_STYLE>';

    function getRadius() public view returns (uint256) { 
        return _maxRadius;
    }
  
    constructor() {
        owner = msg.sender;
        _name = "c";
        _imageBaseURI = ""; // Set to empty string - results in on-chain SVG generation by default unless this is set later
        _imageExtension = ""; // Set to empty string - can be changed later to remain empty, .png, .mp4, etc
        _maxRadius = 2000;

        // Deploy with default SVG image parts - can be completely replaced later
        _imageParts.push("<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='2000' height='2000'>");
            _imageParts.push("<style>");
                _imageParts.push(".m1 #c{fill: #fff;}");
                _imageParts.push(".m1 #r{fill: #000;}");
                _imageParts.push(".m2 #c{fill: #fff;}");
                _imageParts.push(".m2 #r{fill: #10a;}"); // b
                _imageParts.push(".m3 #c{fill: #df0;}"); // y
                _imageParts.push(".m3 #r{fill: #000;}");
                _imageParts.push(".m4 #c{fill: #f00;}"); // r
                _imageParts.push(".m4 #r{fill: #000;}");
                _imageParts.push(".a #c{fill: #000 !important;}"); // b
                _imageParts.push(".a #r{fill: #000 !important;}");
                _imageParts.push(_CLASS_STYLE_TAG);
            _imageParts.push("</style>");
            _imageParts.push("<g class='");
                _imageParts.push(_CLASS_TAG);
                _imageParts.push("'>");
                    _imageParts.push("<rect id='r' width='2000' height='2000'/>");
                    _imageParts.push("<rect id='c' x='");
                        _imageParts.push(_OFFSET_TAG);
                    _imageParts.push("' y='");
                        _imageParts.push(_OFFSET_TAG);
                    _imageParts.push("' width='");
                        _imageParts.push(_RADIUS_TAG);
                    _imageParts.push("' height='");
                        _imageParts.push(_RADIUS_TAG);
                    _imageParts.push("'/>");

            _imageParts.push("</g>");                
        _imageParts.push("</svg>");
    }        
    
    function setName(string calldata name_) external { 
        _requireOnlyOwner();       
        _name = name_;
    }

    function setImageBaseURI(string calldata imageBaseURI_, string calldata imageExtension_) external {        
        _requireOnlyOwner();
        _imageBaseURI = imageBaseURI_;
        _imageExtension = imageExtension_;
    }

    function setMaxRadius(uint256 maxRadius_) external {
        _requireOnlyOwner();
        _maxRadius = maxRadius_;
    }    

    function tokenMetadata(uint256 tokenId, uint256 rarity, uint256 tokenDensity, uint256 alphaDensity, bool isAlpha, uint256 mergeCount) external view override returns (string memory) {        
        string memory base64Json = Base64.encode(bytes(string(abi.encodePacked(_getJson(tokenId, rarity, tokenDensity, alphaDensity, isAlpha, mergeCount)))));
        return string(abi.encodePacked('data:application/json;base64,', base64Json));
    }

    function updateImageParts(string[] memory imageParts_) public {
        _requireOnlyOwner();
        _imageParts = imageParts_;
    }

    function updateClassStyle(string calldata cssClass, string calldata cssStyle) external {
        _requireOnlyOwner();
        _classStyles[cssClass] = cssStyle;
    }

    function getClassStyle(string memory cssClass) public view returns (string memory) {
        return _classStyles[cssClass];
    }

    function name() public view returns (string memory) {
        return _name;
    }

    function imageBaseURI() public view returns (string memory) {
        return _imageBaseURI;
    }

    function imageExtension() public view returns (string memory) {
        return _imageExtension;
    }

    function maxRadius() public view returns (uint256) {
        return _maxRadius;
    }            

    function getClassString(uint256 tokenId, uint256 rarity, bool isAlpha, bool offchainImage) public pure returns (string memory) {
        return _getClassString(tokenId, rarity, isAlpha, offchainImage);
    }

    function _getJson(uint256 tokenId, uint256 rarity, uint256 tokenDensity, uint256 alphaDensity, bool isAlpha, uint256 mergeCount) private view returns (string memory) {        
        string memory imageData = 
            bytes(_imageBaseURI).length == 0 ? 
                _getSvg(tokenId, rarity, tokenDensity, alphaDensity, isAlpha) :
                string(abi.encodePacked(imageBaseURI(), _getClassString(tokenId, rarity, isAlpha, true), "_", uint256(int256(_getScaledRadius(tokenDensity, alphaDensity, _maxRadius).toInt())).toString(), imageExtension()));

        ERC721MetadataStructure memory metadata = ERC721MetadataStructure({
            isImageLinked: bytes(_imageBaseURI).length > 0, 
            name: string(abi.encodePacked(name(), "(", tokenDensity.toString(), ") #", tokenId.toString())),
            description: tokenDensity.toString(),
            createdBy: "Hak",
            image: imageData,
            attributes: _getJsonAttributes(tokenId, rarity, tokenDensity, mergeCount, isAlpha)
        });

        return _generateERC721Metadata(metadata);
    }        

    function _getJsonAttributes(uint256 tokenId, uint256 rarity, uint256 tokenDensity, uint256 mergeCount, bool isAlpha) private pure returns (ERC721MetadataAttribute[] memory) {
        uint256 tensDigit = tokenId % 100 / 10;
        uint256 onesDigit = tokenId % 10;
        uint256 class = tensDigit * 10 + onesDigit;

        ERC721MetadataAttribute[] memory metadataAttributes = new ERC721MetadataAttribute[](5);
        metadataAttributes[0] = _getERC721MetadataAttribute(false, true, false, "", "Density", tokenDensity.toString());
        metadataAttributes[1] = _getERC721MetadataAttribute(false, true, false, "", "Alpha", isAlpha ? "1" : "0");
        metadataAttributes[2] = _getERC721MetadataAttribute(false, true, false, "", "Tier", rarity.toString());
        metadataAttributes[3] = _getERC721MetadataAttribute(false, true, false, "", "Class", class.toString());
        metadataAttributes[4] = _getERC721MetadataAttribute(false, true, false, "", "Combines", mergeCount.toString());
        return metadataAttributes;
    }    

    function _getERC721MetadataAttribute(bool includeDisplayType, bool includeTraitType, bool isValueAString, string memory displayType, string memory traitType, string memory value) private pure returns (ERC721MetadataAttribute memory) {
        ERC721MetadataAttribute memory attribute = ERC721MetadataAttribute({
            includeDisplayType: includeDisplayType,
            includeTraitType: includeTraitType,
            isValueAString: isValueAString,
            displayType: displayType,
            traitType: traitType,
            value: value
        });

        return attribute;
    }    

    function _getSvg(uint256 tokenId, uint256 rarity, uint256 tokenDensity, uint256 alphaDensity, bool isAlpha) private view returns (string memory) {
        bytes memory byteString;
        int128 radius = _getScaledRadius(tokenDensity, alphaDensity, _maxRadius);
        int128 offset = _getOffset(radius, _maxRadius);
        //return _floatToString(offset);
        for (uint i = 0; i < _imageParts.length; i++) {
          if (_checkTag(_imageParts[i], _RADIUS_TAG)) {
            byteString = abi.encodePacked(byteString, _floatToString(radius));
          } else if (_checkTag(_imageParts[i], _OFFSET_TAG)) {
            byteString = abi.encodePacked(byteString, _floatToString(offset));
          } else if (_checkTag(_imageParts[i], _CLASS_TAG)) {
            byteString = abi.encodePacked(byteString, _getClassString(tokenId, rarity, isAlpha, false));
          } else if (_checkTag(_imageParts[i], _CLASS_STYLE_TAG)) {
              uint256 tensDigit = tokenId % 100 / 10;
              uint256 onesDigit = tokenId % 10;
              uint256 class = tensDigit * 10 + onesDigit;
              string memory classCss = getClassStyle(_getTokenIdClass(class));
              if(bytes(classCss).length > 0) {
                  byteString = abi.encodePacked(byteString, classCss);
              }            
          } else {
            byteString = abi.encodePacked(byteString, _imageParts[i]);
          }
        }
        return string(byteString); 
    }

    function _getScaledRadius(uint256 tokenDensity, uint256 alphaDensity, uint256 maximumRadius) private pure returns (int128) {
        int128 radiusDensity = _getRadius64x64(tokenDensity);
        int128 radiusAlphaDensity = _getRadius64x64(alphaDensity);
        int128 scalePercentage = ABDKMath64x64.div(radiusDensity, radiusAlphaDensity);                
        int128 scaledRadius = ABDKMath64x64.mul(ABDKMath64x64.fromUInt(maximumRadius), scalePercentage);
        if(uint256(int256(scaledRadius.toInt())) == 0) {
            scaledRadius = ABDKMath64x64.fromUInt(1);
        }
        return scaledRadius;
    }

    function _getOffset(int128 radius, uint256 maximumRadius) private pure returns (int128) {
        
        int128 remainLength = ABDKMath64x64.sub(ABDKMath64x64.fromUInt(maximumRadius), radius);                
        int128 offset = ABDKMath64x64.div(remainLength, ABDKMath64x64.fromUInt(2));
        if(uint256(int256(offset.toInt())) == 0) {
            offset = ABDKMath64x64.fromUInt(0);
        }
        return offset;
    }

    // Radius = Cube Root(Density) * Cube Root (0.23873241463)
    // Radius = Cube Root(Density) * 0.62035049089
    function _getRadius64x64(uint256 density) private pure returns (int128) {        
        int128 cubeRootScalar = ABDKMath64x64.divu(62035049089, 100000000000);
        int128 cubeRootDensity = ABDKMath64x64.divu(density.nthRoot(3, 6, 32), 1000000);
        int128 radius = ABDKMath64x64.mul(cubeRootDensity, cubeRootScalar);        
        return radius;
    }            

    function _generateERC721Metadata(ERC721MetadataStructure memory metadata) private pure returns (string memory) {
      bytes memory byteString;    
    
        byteString = abi.encodePacked(
          byteString,
          _openJsonObject());
    
        byteString = abi.encodePacked(
          byteString,
          _pushJsonPrimitiveStringAttribute("name", metadata.name, true));
    
        byteString = abi.encodePacked(
          byteString,
          _pushJsonPrimitiveStringAttribute("description", metadata.description, true));
    
        byteString = abi.encodePacked(
          byteString,
          _pushJsonPrimitiveStringAttribute("created_by", metadata.createdBy, true));
    
        if(metadata.isImageLinked) {
            byteString = abi.encodePacked(
                byteString,
                _pushJsonPrimitiveStringAttribute("image", metadata.image, true));
        } else {
            byteString = abi.encodePacked(
                byteString,
                _pushJsonPrimitiveStringAttribute("image_data", metadata.image, true));
        }

        byteString = abi.encodePacked(
          byteString,
          _pushJsonComplexAttribute("attributes", _getAttributes(metadata.attributes), false));
    
        byteString = abi.encodePacked(
          byteString,
          _closeJsonObject());
    
        return string(byteString);
    }

    function _getAttributes(ERC721MetadataAttribute[] memory attributes) private pure returns (string memory) {
        bytes memory byteString;
    
        byteString = abi.encodePacked(
          byteString,
          _openJsonArray());
    
        for (uint i = 0; i < attributes.length; i++) {
          ERC721MetadataAttribute memory attribute = attributes[i];

          byteString = abi.encodePacked(
            byteString,
            _pushJsonArrayElement(_getAttribute(attribute), i < (attributes.length - 1)));
        }
    
        byteString = abi.encodePacked(
          byteString,
          _closeJsonArray());
    
        return string(byteString);
    }

    function _getAttribute(ERC721MetadataAttribute memory attribute) private pure returns (string memory) {
        bytes memory byteString;
        
        byteString = abi.encodePacked(
          byteString,
          _openJsonObject());
    
        if(attribute.includeDisplayType) {
          byteString = abi.encodePacked(
            byteString,
            _pushJsonPrimitiveStringAttribute("display_type", attribute.displayType, true));
        }
    
        if(attribute.includeTraitType) {
          byteString = abi.encodePacked(
            byteString,
            _pushJsonPrimitiveStringAttribute("trait_type", attribute.traitType, true));
        }
    
        if(attribute.isValueAString) {
          byteString = abi.encodePacked(
            byteString,
            _pushJsonPrimitiveStringAttribute("value", attribute.value, false));
        } else {
          byteString = abi.encodePacked(
            byteString,
            _pushJsonPrimitiveNonStringAttribute("value", attribute.value, false));
        }
    
        byteString = abi.encodePacked(
          byteString,
          _closeJsonObject());
    
        return string(byteString);
    }

    function _getClassString(uint256 tokenId, uint256 rarity, bool isAlpha, bool offchainImage) private pure returns (string memory) {
        bytes memory byteString;    
    
        byteString = abi.encodePacked(byteString, _getRarityClass(rarity));
        
        if(isAlpha) {
            byteString = abi.encodePacked(
              byteString,
              string(abi.encodePacked(offchainImage ? "_" : " ", "a")));
        }

        uint256 tensDigit = tokenId % 100 / 10;
        uint256 onesDigit = tokenId % 10;
        uint256 class = tensDigit * 10 + onesDigit;

        byteString = abi.encodePacked(
          byteString,
          string(abi.encodePacked(offchainImage ? "_" : " ", _getTokenIdClass(class))));

        return string(byteString);    
    }

    function _getRarityClass(uint256 rarity) private pure returns (string memory) {
        return string(abi.encodePacked("m", rarity.toString()));
    }

    function _getTokenIdClass(uint256 class) private pure returns (string memory) {
        return string(abi.encodePacked("c", class.toString()));
    }

    function _checkTag(string storage a, string memory b) private pure returns (bool) {
        return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
    }

    function _floatToString(int128 value) private pure returns (string memory) {
        uint256 decimal4 = (value & 0xFFFFFFFFFFFFFFFF).mulu(10000);
        return string(abi.encodePacked(uint256(int256(value.toInt())).toString(), '.', _decimal4ToString(decimal4)));
    }
  
    function _decimal4ToString(uint256 decimal4) private pure returns (string memory) {
        bytes memory decimal4Characters = new bytes(4);
        for (uint i = 0; i < 4; i++) {
          decimal4Characters[3 - i] = bytes1(uint8(0x30 + decimal4 % 10));
          decimal4 /= 10;
        }
        return string(abi.encodePacked(decimal4Characters));
    }

    function _requireOnlyOwner() private view {
        require(msg.sender == owner, "You are not the owner");
    }

    function _openJsonObject() private pure returns (string memory) {        
        return string(abi.encodePacked("{"));
    }

    function _closeJsonObject() private pure returns (string memory) {
        return string(abi.encodePacked("}"));
    }

    function _openJsonArray() private pure returns (string memory) {        
        return string(abi.encodePacked("["));
    }

    function _closeJsonArray() private pure returns (string memory) {        
        return string(abi.encodePacked("]"));
    }

    function _pushJsonPrimitiveStringAttribute(string memory key, string memory value, bool insertComma) private pure returns (string memory) {
        return string(abi.encodePacked('"', key, '": "', value, '"', insertComma ? ',' : ''));
    }

    function _pushJsonPrimitiveNonStringAttribute(string memory key, string memory value, bool insertComma) private pure returns (string memory) {
        return string(abi.encodePacked('"', key, '": ', value, insertComma ? ',' : ''));
    }

    function _pushJsonComplexAttribute(string memory key, string memory value, bool insertComma) private pure returns (string memory) {
        return string(abi.encodePacked('"', key, '": ', value, insertComma ? ',' : ''));
    }

    function _pushJsonArrayElement(string memory value, bool insertComma) private pure returns (string memory) {
        return string(abi.encodePacked(value, insertComma ? ',' : ''));
    }
}
// File: Combine.sol


pragma solidity ^0.8.6;


interface IERC721Receiver {
    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}

interface IERC165 {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

interface ERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    function balanceOf(address owner) external view returns (uint256 balance);
    function ownerOf(uint256 tokenId) external view returns (address owner);
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function transferFrom(address from, address to, uint256 tokenId) external;

    function approve(address to, uint256 tokenId) external;
    function getApproved(uint256 tokenId) external view returns (address operator);
    function setApprovalForAll(address operator, bool _approved) external;
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

interface ERC721Metadata {
    function name() external view returns (string memory _name);
    function symbol() external view returns (string memory _symbol);
    function tokenURI(uint256 _tokenId) external view returns (string memory);
}

contract Combine is ERC721, ERC721Metadata {
 
    ICombineMetadata public _metadataGenerator;

    bool public frozen;

    string private _name;
    string private _symbol;

    uint256 constant private CLASS_MULTIPLIER = 100000; // 100k

    // valid classes are in the range [1, 4]
    uint256 constant private MIN_CLASS_INCL = 1; 
    uint256 constant private MAX_CLASS_INCL = 4;

    // valid densities are in the range [1, 100k - 1]
    uint256 constant private MIN_DENSITY_INCL = 1; 
    uint256 constant private MAX_DENSITY_EXCL = CLASS_MULTIPLIER - 1;

    uint256 public _saleStartTime = 1640969999;
    uint256 public _saleEndTime = 1699999999;

    uint256 public _maxSupply = 5000;
    uint256 public _maxDensity = 25000;

    uint256 public _unitPrice = 25e15;

    uint256 public _freeIndex = 101;
 
    uint256 public _nextMintId;
 
    uint256 public _countToken;

    uint256 immutable public _percentageTotal;
    uint256 public _percentageRoyalty;

    uint256 public _alphaDensity;

    uint256 public _alphaId;

    uint256 public _densityTotal;

    address public _hak;
    address public _collab;
    address public _fund;
    address public _receiver;
    address constant public _dead = 0x000000000000000000000000000000000000dEaD;

    event AlphaDensityUpdate(uint256 indexed tokenId, uint256 alphaDensity);

    event DensityUpdate(uint256 indexed tokenIdBurned, uint256 indexed tokenIdPersist, uint256 density);

    uint256[5001] private _tokenIdArray;

    mapping (uint256 => uint256) private _tokenIdToIndex;

    // Mapping of addresses disbarred from holding any token.
    mapping (address => bool) private _blacklistAddress;

    // Mapping of address allowed to hold multiple tokens.
    mapping (address => bool) private _whitelistAddress;

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

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

    // Mapping token ID to density value.
    mapping (uint256 => uint256) private _values;

    // Mapping token ID to all quantity combined into it.
    mapping (uint256 => uint256) private _combineCount;

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

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

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


    function getCombineCount(uint256 tokenId) public view returns (uint256 combineCount) {
        require(_exists(tokenId), "nonexistent token");
        return _combineCount[tokenId];
    }

    function getTokenIdFromArray(uint256 index) public view returns (uint256 tokenId) {
        return _tokenIdArray[index];
    }

    function getIndexFromTokenId(uint256 tokenId) public view returns (uint256 index) {
        return _tokenIdToIndex[tokenId];
    }

    modifier onlyHak() {
        require(_msgSender() == _hak, "msg.sender is not hak");
        _;
    }

    modifier onlyValidWhitelist() {
        require(_whitelistAddress[_msgSender()], "invalid msg.sender");
        _;
    }

    modifier notFrozen() {
        require(!frozen, "transfer frozen");
        _;
    }

    function ensureValidClass(uint256 class) private pure {
        require(MIN_CLASS_INCL <= class && class <= MAX_CLASS_INCL, "class must be [1,4].");
    }

    function ensureValidDensity(uint256 density) private pure {
        require(MIN_DENSITY_INCL <= density && density < MAX_DENSITY_EXCL, "density must be [1,100k-1).");
    }
   
    constructor(address metadataGenerator_, address collab_, address fund_) {

        _metadataGenerator = ICombineMetadata(metadataGenerator_);
        _name = "combine.";
        _symbol = "c";

        _hak = msg.sender;
        _collab = collab_;
        _fund = fund_;
        _receiver = _hak;

        _percentageTotal = 10000;
        _percentageRoyalty = 1000;

        _blacklistAddress[address(this)] = true;            

        // mint one with density 10 to act as placeholder alpha
        _values[1] = encodeClassAndDensity(1, 10);         
        _owners[1] = msg.sender;
        _tokens[msg.sender] = 1;
        emit Transfer(address(0), msg.sender, 1);
        _countToken++;
        _balances[msg.sender]++;
        _densityTotal = 10;
        _alphaDensity = 10;
        _alphaId = 1;
        emit AlphaDensityUpdate(1, 10);

        _tokenIdToIndex[1] = 1;
        _tokenIdArray[_countToken] = 1;
        _nextMintId = 2;
    }
        
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    } 

    function totalSupply() public view returns (uint256) {
        return _countToken;
    }
 
    function combine(uint256 tokenIdRcvr, uint256 tokenIdSndr) external onlyValidWhitelist notFrozen returns (uint256 tokenIdDead) {        
        address owner = ownerOf(tokenIdRcvr);
        require(owner == ownerOf(tokenIdSndr), "disparate owner");
        require(_msgSender() == owner, "not token owner.");

        // owners are same, so decrement their balance as we are merging
        _balances[owner] -= 1;

        tokenIdDead = _combine(tokenIdRcvr, tokenIdSndr);

        // clear ownership of dead token
        delete _owners[tokenIdDead];

        // owners are the same; burn dead token from common owner
        emit Transfer(owner, address(0), tokenIdDead);
    }

    function _transfer(address owner, address from, address to, uint256 tokenId) internal notFrozen {
        require(owner == from, "token not own");
        require(to != address(0), "cannot transfer to zero addr");
        require(!_blacklistAddress[to], "cannot transfer to blacklist");

        // if transferring to `_dead_` then `_transfer` is interpreted as a burn
        if (to == _dead) {
            _burnNoEmitTransfer(owner, tokenId);

            emit Transfer(from, _dead, tokenId);
            emit Transfer(_dead, address(0), tokenId);
        } else {
            // Clear any prior approvals
            // includes an emit of Approval to zero
            _approve(owner, address(0), tokenId);

            // in all cases we first wish to log the transfer
            // no merging later can deny the fact that `from` transferred to `to`
            emit Transfer(from, to, tokenId);

            if (from == to) {
                // !non-local control flow!
                // we make an exception here, as it’s easy to follow that a self transfer
                // can skip _all_ following state changes
                return;
            }

            // if all addresses were whitelisted, then transfer would be like any other ERC-721
            // _balances[from] -= 1;
            // _balances[to] += 1;
            // _owners[tokenId] = to;

            // _balances (1) and _owners (2) are the main mappings to update
            // for non-whitelisted addresses there is also the _tokens (3) mapping
            //
            // Our updates will be
            //   - 1a: decrement balance of `from`
            //   - 1b: update balance of `to` (not guaranteed to increase)
            //   - 2: assign ownership of `tokenId`
            //   - 3a: assign unique token of `to`
            //   - 3b: unassign unique token of `from`

            bool fromIsWhitelisted = isWhitelisted(from);
            bool toIsWhitelisted = isWhitelisted(to);

            // BEGIN PART 1: update _balances
            //
            // PART 1a: decrease balance of `from`
            //   the classic implementation would be
            //   _balances[from] -= 1;
            if (fromIsWhitelisted) {
                // from the reasoning:
                // > if all addresses were whitelisted, then transfer would be like any other ERC-721
                _balances[from] -= 1;
            } else {
                // for non-whitelisted addresses, we have the invariant that
                //   _balances[a] <= 1
                // we known that `from` was the owner so the only possible state is
                //   _balances[from] == 1
                // to save an SLOAD, we can assign a balance of 0 (or delete)
                delete _balances[from];
            }
            // PART 1b: increase balance of `to`
            //   the classic implementation would be
            //   _balances[to] += 1;
            if (toIsWhitelisted) {
                // from the reasoning:
                // > if all addresses were whitelisted, then transfer would be like any other ERC-721
                _balances[to] += 1;
            } else if (_tokens[to] == 0) {
                // for non-whitelisted addresses, we have the invariant that
                //   _balances[a] <= 1
                // if _tokens[to] == 0 then _balances[to] == 0
                // to save an SLOAD, we can assign a balance of 1
                _balances[to] = 1;
            } else {
                // for non-whitelisted addresses, we have the invariant that
                //   _balances[a] <= 1
                // if _tokens[to] != 0 then _balance[to] == 1
                // to preserve the invariant, we have nothing to do (the balance is already 1)
            }
            // END PART 1

            if (toIsWhitelisted) {
                // PART 2: update _owners
                // assign ownership of token
                //   the classic implementation would be
                //   _owners[tokenId] = to;
                //
                // from the reasoning:
                // > if all addresses were whitelisted, then transfer would be like any other ERC-721
                _owners[tokenId] = to;
            } else {
                // label current and sent token with respect to address `to`
                uint256 currentTokenId = _tokens[to];

                if (currentTokenId == 0) {
                    // PART 2: update _owners
                    // assign ownership of token
                    _owners[tokenId] = to;

                    // PART 3a
                    // assign unique token of `to`
                    _tokens[to] = tokenId;
                } else {
                    uint256 sentTokenId = tokenId;

                    // compute token combine, returning the dead token
                    uint256 deadTokenId = _combine(currentTokenId, sentTokenId);

                    // logically, the token has already been transferred to `to`
                    // so log the burning of the dead token id as originating ‘from’ `to`
                    emit Transfer(to, address(0), deadTokenId);

                    // thus inferring the alive token
                    uint256 aliveTokenId = currentTokenId;
                    if (currentTokenId == deadTokenId) {
                        aliveTokenId = sentTokenId;
                    }

                    // PART 2 continued:
                    // and ownership of dead token is deleted
                    delete _owners[deadTokenId];

                    // if received token surplanted the current token
                    if (currentTokenId != aliveTokenId) {
                        // PART 2 continued:
                        // to takes ownership of alive token
                        _owners[aliveTokenId] = to;

                        // PART 3a
                        // assign unique token of `to`
                        _tokens[to] = aliveTokenId;
                    }
                }
            }

            // PART 3b:
            // unassign unique token of `from`
            //
            // _tokens is only defined for non-whitelisted addresses
            if (!fromIsWhitelisted) {
                delete _tokens[from];
            }
        }
    }

    function _increaseDensity(uint256 tokenId, uint256 density_) private {
        uint256 currentDensity = decodeDensity(_values[tokenId]);
        _values[tokenId] += density_;

        uint256 newDensity = currentDensity + density_;

        if(newDensity > _alphaDensity) {
            _alphaId = tokenId;
            _alphaDensity = newDensity;
            emit AlphaDensityUpdate(_alphaId, newDensity);
        }

        emit DensityUpdate(0, tokenId, newDensity);
    }

    function _combine(uint256 tokenIdRcvr, uint256 tokenIdSndr) internal returns (uint256 tokenIdDead) {
        require(tokenIdRcvr != tokenIdSndr, "identical tokenId");

        uint256 densityRcvr = decodeDensity(_values[tokenIdRcvr]);
        uint256 densitySndr = decodeDensity(_values[tokenIdSndr]);
        
        uint256 densitySmall = densityRcvr;
        uint256 densityLarge = densitySndr;

        uint256 tokenIdSmall = tokenIdRcvr;
        uint256 tokenIdLarge = tokenIdSndr;

        if (densityRcvr >= densitySndr) {

            densitySmall = densitySndr;
            densityLarge = densityRcvr;

            tokenIdSmall = tokenIdSndr;
            tokenIdLarge = tokenIdRcvr;
        }

        _values[tokenIdLarge] += densitySmall;

        uint256 combinedDensity = densityLarge + densitySmall;

        if(combinedDensity > _alphaDensity) {
            _alphaId = tokenIdLarge;
            _alphaDensity = combinedDensity;
            emit AlphaDensityUpdate(_alphaId, combinedDensity);
        }
        
        _combineCount[tokenIdLarge]++;

        delete _values[tokenIdSmall];

        uint256 indexToReplace = _tokenIdToIndex[tokenIdSmall];
        uint256 lastTokenId = _tokenIdArray[_countToken];
        _tokenIdArray[indexToReplace] = lastTokenId;
        _tokenIdToIndex[lastTokenId] = indexToReplace;
        _countToken--;

        emit DensityUpdate(tokenIdSmall, tokenIdLarge, combinedDensity);

        return tokenIdSmall;
    }

    function setRoyaltyBips(uint256 percentageRoyalty_) external onlyHak {
        require(percentageRoyalty_ <= _percentageTotal, "more than 100%");
        _percentageRoyalty = percentageRoyalty_;
    }

    function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256) {
        uint256 royaltyAmount = (salePrice * _percentageRoyalty) / _percentageTotal;
        return (_receiver, royaltyAmount);
    }

    function setBlacklistAddress(address address_, bool status) external onlyHak {
        _blacklistAddress[address_] = status;
    }

    function setCollab(address collab_) external onlyHak {  
        _collab = collab_;
    }

    function setFund(address fund_) external onlyHak {  
        _fund = fund_;
    }

    function setHak(address hak_) external onlyHak {
        require(address(this).balance < 1e16, "be careful");
        _hak = hak_;
    }

    function setUnitPrice(uint256 unitPrice_) external onlyHak {
        _unitPrice = unitPrice_;
    }

    function setSaleStartTime(uint256 startTime_) external onlyHak {
        require(
            startTime_ < _saleEndTime,
            "invalid time"
        );
        _saleStartTime = startTime_;
    }

    function setSaleEndTime(uint256 endTime_) external onlyHak {
        require(
            _saleStartTime < endTime_,
            "invalid time"
        );
        _saleEndTime = endTime_;
    }

    function setMaxSupply(uint256 count_) external onlyHak {
        require(_nextMintId <= count_, "invalid supply count");
        _maxSupply = count_;
    }

    function setFreeIndex(uint256 index_) external onlyHak {
        require(_nextMintId <= index_ && index_ <= _maxSupply, "invalid index");
        _freeIndex = index_;
    }
    
    function setMaxDensity(uint256 density_) external onlyHak {
        require(_densityTotal <= density_ && density_ <= MAX_DENSITY_EXCL, "invalid density");
        _maxDensity = density_;
    }

    function setRoyaltyReceiver(address receiver_) external onlyHak {  
        _receiver = receiver_;
    }
    
    function setMetadataGenerator(address metadataGenerator_) external onlyHak {  
        _metadataGenerator = ICombineMetadata(metadataGenerator_);
    }
   
    function whitelistUpdate(address address_, bool status) external onlyHak {

        if(status == false) {
            require(balanceOf(address_) <= 1, "addr cannot be removed");
        }

        _whitelistAddress[address_] = status;
    }

    function isWhitelisted(address address_) public view returns (bool) {
        return _whitelistAddress[address_];
    }

    function isBlacklisted(address address_) public view returns (bool) {
        return _blacklistAddress[address_];
    }

    function ownerOf(uint256 tokenId) public view override returns (address owner) {
        owner = _owners[tokenId]; 
        require(owner != address(0), "nonexistent token");
    }

    /**
     *
     *
     * _densityToMint - density of the cube you want to mint
     *
     * Emits a series of {Transfer} events.
     */
    function mint(uint256 _densityToMint) external payable {
        require(
            block.timestamp >= _saleStartTime && block.timestamp < _saleEndTime,
            "sale not open"
        );
        require(_nextMintId < _maxSupply, "max supply reached");
        // require(
        //     _balances[msg.sender] == 0,
        //     "cannot mint while holding cube"
        // );
        require(
            tx.origin == msg.sender,
            "cannot use custom contract"
        );

        bool ownACube = _balances[msg.sender] != 0;
        
        // for efficiency reasons copy from storage into local variables
        uint256 index = _nextMintId;
        uint256 alphaId = _alphaId;
        uint256 alphaDensity = _alphaDensity;

        uint256 paidCount = _densityToMint;

        if (msg.sender == _hak){
            paidCount = 0;
        
        } // first few are free for density 1 (nonholder only)
        else if (index <= _freeIndex && !ownACube){
            paidCount--;
        }

        require(
            msg.value >= paidCount * _unitPrice,
            "insufficient ETH"
        );

        // update total density in system (must be bounded by MAX_DENSITY_EXCL)
        uint256 prevDensityTotal = _densityTotal;
        uint256 newDensityTotal = prevDensityTotal + _densityToMint;
        require(
            newDensityTotal <= _maxDensity,
            "total max density reached"
        );
        _densityTotal = newDensityTotal;

        // IF owner already has a cube, simply update the density of that cube
        if (ownACube){
            require(!isWhitelisted(msg.sender), "cannot update wl density");
            _increaseDensity(tokenOf(msg.sender), _densityToMint);
            return;
        }

        // 5% of having a special background
        uint256 class = (random() % 100) < 5 ? 2 : 1;

        _values[index] = encodeClassAndDensity(class, _densityToMint);         
        _owners[index] = msg.sender;


        // update token supply
        _countToken++;

        if (alphaDensity < _densityToMint){
            alphaDensity = _densityToMint;
            alphaId = index;
        }

        _tokenIdArray[index] = index;
        _tokenIdToIndex[index] = index;

        _transfer(address(0), address(0), msg.sender, index);
        //emit Transfer(address(0), msg.sender, index);

        index++;
        // return new token id index to storage
        _nextMintId = index; 


        // if the alpha was supplanted, return that new state to storage
        if(_alphaId != alphaId) {
            _alphaId = alphaId;
            _alphaDensity = alphaDensity;
            emit AlphaDensityUpdate(alphaId, alphaDensity);
        }        
    }

    function random() private view returns (uint256) {
        // pseudorandom
        bytes32 randomHash = keccak256(
            abi.encode(
                block.timestamp,
                block.difficulty,
                block.coinbase,
                msg.sender
            )
        );
        return uint256(randomHash);
    }
   

    function freeze(bool state_) external onlyHak {
        frozen = state_;
    }

    function _destroy(uint256 tokenId) private {
        address owner = _owners[tokenId];
        require(owner != address(0), "nonexistent token");
        _burnNoEmitTransfer(owner, tokenId);
        if (msg.value > 0){
            (bool success,) = owner.call{value: msg.value}("");
            require(success, "transfer failed");
        }
        emit Transfer(owner, address(0), tokenId);
    }

    function destroyWithMercy(uint256 tokenId) external payable onlyHak {
        _destroy(tokenId);
    }

    function destroyRandomWithMercy() external payable onlyHak {
        uint256 tokenId = _tokenIdArray[(random() % (_countToken)) + 1];
        uint256 newTokenId;
        while ((random() % _alphaDensity) > densityOf(tokenId)){
            newTokenId = _tokenIdArray[(random() % (_countToken)) + 1];
            if (tokenId == newTokenId){
                break;
            } else {
                tokenId = newTokenId;
            }
        }
        _destroy(tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
        transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "non ERC721Receiver implementer");
    }

    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        (address owner, bool isApprovedOrOwner) = _isApprovedOrOwner(_msgSender(), tokenId);
        require(isApprovedOrOwner, "not owner nor approved");
        _transfer(owner, from, to, tokenId);
    }

    function balanceOf(address owner) public view override returns (uint256) {
        return _balances[owner];        
    }

    function densityOf(uint256 tokenId) public view virtual returns (uint256) {
        uint256 value = getValueOf(tokenId);
        return decodeDensity(value);
    }

    function getValueOf(uint256 tokenId) public view virtual returns (uint256 value) {
        value = _values[tokenId];
        require(value != 0, "nonexistent token");
    }

    function tokenOf(address owner) public view virtual returns (uint256) {
        require(!isWhitelisted(owner), "tokenOf undefined");
        uint256 token = _tokens[owner];
        return token;
    }

    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ownerOf(tokenId);
        require(to != owner, "approval to current owner");

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "not owner nor approved for all"
        );
        _approve(owner, to, tokenId);
    }

    function _approve(address owner, address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "nonexistent token");       
        return _tokenApprovals[tokenId];
    }

    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "approve to caller");
        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

    function exists(uint256 tokenId) public view returns (bool) {
        return _exists(tokenId);
    }

    function _exists(uint256 tokenId) internal view returns (bool) {
        return _owners[tokenId] != address(0);
    }

    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (address owner, bool isApprovedOrOwner) {
        owner = _owners[tokenId];

        require(owner != address(0), "nonexistent token");

        isApprovedOrOwner = (spender == owner || _tokenApprovals[tokenId] == spender || isApprovedForAll(owner, spender));
    }   

    function tokenURI(uint256 tokenId) public virtual view override returns (string memory) {
        require(_exists(tokenId), "nonexistent token");
        
        return _metadataGenerator.tokenMetadata(
            tokenId, 
            decodeClass(_values[tokenId]), 
            decodeDensity(_values[tokenId]), 
            decodeDensity(_values[_alphaId]), 
            tokenId == _alphaId,
            getCombineCount(tokenId));
    }

    function updateTokenClass(uint tokenId, uint256 class) external onlyHak {
        require(_exists(tokenId), "nonexistent token");
        _values[tokenId] = encodeClassAndDensity(class, densityOf(tokenId));
    }

    function encodeClassAndDensity(uint256 class, uint256 density) public pure returns (uint256) {
        ensureValidClass(class);
        ensureValidDensity(density);
        return ((class * CLASS_MULTIPLIER) + density);
    }

    function decodeClassAndDensity(uint256 value) public pure returns (uint256, uint256) {
        uint256 class = decodeClass(value);
        uint256 density = decodeDensity(value);
        return (class, density);
    }

    function decodeClass(uint256 value) public pure returns (uint256 class) {
        class = value / CLASS_MULTIPLIER; // integer division is ‘checked’ in Solidity 0.8.x
        ensureValidClass(class);
    }    

    function decodeDensity(uint256 value) public pure returns (uint256 density) {
        density = value % CLASS_MULTIPLIER; // integer modulo is ‘checked’ in Solidity 0.8.x
        ensureValidDensity(density);
    }

    function _msgSender() internal view returns (address) {
        return msg.sender;
    }

    function withdrawAll() public onlyHak {
        uint256 currentBal = address(this).balance;
        require(currentBal > 0);
        if (_collab == _hak){
            _withdraw(_hak, address(this).balance);
        } else {
            _withdraw(_collab, currentBal / 4); // 25%
            _withdraw(_fund, currentBal / 2); // 50%
            //remainder to prevent ether dust
            _withdraw(_hak, address(this).balance); // 25%
        }
    }

    function _withdraw(address _addr, uint256 _amt) private {
        (bool success,) = _addr.call{value: _amt}("");
        require(success, "transfer failed");
    }
     
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) {
        if (isContract(to)) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("non ERC721Receiver implementer");
                }
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
        return true;
    }    

    function isContract(address account) internal view returns (bool) {
        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        bytes4 _ERC165_ = 0x01ffc9a7;
        bytes4 _ERC721_ = 0x80ac58cd;
        bytes4 _ERC2981_ = 0x2a55205a;
        bytes4 _ERC721Metadata_ = 0x5b5e139f;
        return interfaceId == _ERC165_ 
            || interfaceId == _ERC721_
            || interfaceId == _ERC2981_
            || interfaceId == _ERC721Metadata_;
    }


    function burn(uint256 tokenId) public notFrozen {
        (address owner, bool isApprovedOrOwner) = _isApprovedOrOwner(_msgSender(), tokenId);
        require(isApprovedOrOwner, "not owner nor approved");

        _burnNoEmitTransfer(owner, tokenId);

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

    function _burnNoEmitTransfer(address owner, uint256 tokenId) internal {
        _approve(owner, address(0), tokenId);

        _densityTotal -= decodeDensity(_values[tokenId]);

        delete _tokens[owner];
        delete _owners[tokenId];
        delete _values[tokenId];

        uint256 indexToReplace = _tokenIdToIndex[tokenId];
        uint256 lastTokenId = _tokenIdArray[_countToken];
        _tokenIdArray[indexToReplace] = lastTokenId;
        _tokenIdToIndex[lastTokenId] = indexToReplace;
        _countToken--;



        _balances[owner] -= 1;        

        emit DensityUpdate(tokenId, 0, 0);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"metadataGenerator_","type":"address"},{"internalType":"address","name":"collab_","type":"address"},{"internalType":"address","name":"fund_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"alphaDensity","type":"uint256"}],"name":"AlphaDensityUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenIdBurned","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"tokenIdPersist","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"density","type":"uint256"}],"name":"DensityUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_alphaDensity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_alphaId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_collab","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_countToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_dead","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_densityTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_freeIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_fund","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_hak","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxDensity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_metadataGenerator","outputs":[{"internalType":"contract ICombineMetadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_nextMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_percentageRoyalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_percentageTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_receiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_saleEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_saleStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_unitPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenIdRcvr","type":"uint256"},{"internalType":"uint256","name":"tokenIdSndr","type":"uint256"}],"name":"combine","outputs":[{"internalType":"uint256","name":"tokenIdDead","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"decodeClass","outputs":[{"internalType":"uint256","name":"class","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"decodeClassAndDensity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"decodeDensity","outputs":[{"internalType":"uint256","name":"density","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"densityOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"destroyRandomWithMercy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"destroyWithMercy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"class","type":"uint256"},{"internalType":"uint256","name":"density","type":"uint256"}],"name":"encodeClassAndDensity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"state_","type":"bool"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"frozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCombineCount","outputs":[{"internalType":"uint256","name":"combineCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getIndexFromTokenId","outputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getTokenIdFromArray","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getValueOf","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_densityToMint","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setBlacklistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collab_","type":"address"}],"name":"setCollab","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index_","type":"uint256"}],"name":"setFreeIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fund_","type":"address"}],"name":"setFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"hak_","type":"address"}],"name":"setHak","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"density_","type":"uint256"}],"name":"setMaxDensity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count_","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"metadataGenerator_","type":"address"}],"name":"setMetadataGenerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"percentageRoyalty_","type":"uint256"}],"name":"setRoyaltyBips","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"}],"name":"setRoyaltyReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"endTime_","type":"uint256"}],"name":"setSaleEndTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startTime_","type":"uint256"}],"name":"setSaleStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"unitPrice_","type":"uint256"}],"name":"setUnitPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokenOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"class","type":"uint256"}],"name":"updateTokenClass","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"whitelistUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040526361cf370f600355636553f0ff6004556113886005556161a86006556658d15e1762800060075560656008553480156200003d57600080fd5b50604051620043183803806200431883398101604081905262000060916200049f565b600080546001600160a01b0319166001600160a01b0385161790556040805180820190915260088082526731b7b6b134b7329760c11b6020909201918252620000ac91600191620003dc565b50604080518082019091526001808252606360f81b6020909201918252620000d791600291620003dc565b50600f8054336001600160a01b031991821681179092556010805482166001600160a01b03868116919091179091556011805483169185169190911790556012805490911690911790556127106080526103e8600b5530600090815261139d60205260409020805460ff191660019081179091556200015890600a620002cb565b7f52720b109a02538e76b28c1d71d4649ce6f5aaeee2824746084acf71af20c71a557f4b7b132a0111b8646ad8b973d4f43f9f1d49318338b2f5ae83f3ef157877766a80546001600160a01b03191633908117909155600081815261139f60205260408082206001908190559051909291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4600a80549060006200020183620004ff565b90915550503360009081526113a0602052604081208054916200022483620004ff565b9091555050600a600e819055600c8190556001600d819055604051918252907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a26001600081905261139c6020527ff8d445471faa4e45902923d2d366e37efb6bb1f72ccdac568a5c46e4df804876819055600a546013906113898110620002bb57620002bb6200051d565b01555050600260095550620005c7565b6000620002d88362000306565b620002e3826200036e565b81620002f3620186a08562000533565b620002ff919062000555565b9392505050565b8060011115801562000319575060048111155b6200036b5760405162461bcd60e51b815260206004820152601460248201527f636c617373206d757374206265205b312c345d2e00000000000000000000000060448201526064015b60405180910390fd5b50565b806001111580156200038e57506200038b6001620186a062000570565b81105b6200036b5760405162461bcd60e51b815260206004820152601b60248201527f64656e73697479206d757374206265205b312c3130306b2d31292e0000000000604482015260640162000362565b828054620003ea906200058a565b90600052602060002090601f0160209004810192826200040e576000855562000459565b82601f106200042957805160ff191683800117855562000459565b8280016001018555821562000459579182015b82811115620004595782518255916020019190600101906200043c565b50620004679291506200046b565b5090565b5b808211156200046757600081556001016200046c565b80516001600160a01b03811681146200049a57600080fd5b919050565b600080600060608486031215620004b557600080fd5b620004c08462000482565b9250620004d06020850162000482565b9150620004e06040850162000482565b90509250925092565b634e487b7160e01b600052601160045260246000fd5b6000600019821415620005165762000516620004e9565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000816000190483118215151615620005505762000550620004e9565b500290565b600082198211156200056b576200056b620004e9565b500190565b600082821015620005855762000585620004e9565b500390565b600181811c908216806200059f57607f821691505b60208210811415620005c157634e487b7160e01b600052602260045260246000fd5b50919050565b608051613d27620005f160003960008181610a6c0152818161139501526119a50152613d276000f3fe6080604052600436106104655760003560e01c8063525f8a5c11610243578063a755516011610143578063dbf65de0116100bb578063e985e9c51161008a578063ec259d171161006f578063ec259d1714610cf0578063fb1fac1814610d10578063fe575a8714610d2657600080fd5b8063e985e9c514610c86578063eafe706e14610cd057600080fd5b8063dbf65de014610c1a578063dc1b732814610c3a578063dcfb383314610c5a578063dde502d114610c7057600080fd5b8063b88d4fde11610112578063c87b56dd116100f7578063c87b56dd14610bba578063cbd14a7d14610bda578063d132391a14610bfa57600080fd5b8063b88d4fde14610b7a578063b8d4a4aa14610b9a57600080fd5b8063a755516014610af6578063a819e4e414610b16578063a8a07b3614610b2c578063b5bf15e514610b5a57600080fd5b8063853828b6116101d65780639121ac0d116101a557806395d89b411161018a57806395d89b4114610aae578063a0712d6814610ac3578063a22cb46514610ad657600080fd5b80639121ac0d14610a5a5780639377736914610a8e57600080fd5b8063853828b6146109f25780638a50fecb14610a075780638dc251e314610a2757806390b5098814610a4757600080fd5b80636f8b44b0116102125780636f8b44b01461096557806370a082311461098557806375a99b9f146109bc57806378907bf7146109d257600080fd5b8063525f8a5c146108e557806355d5f96314610905578063629a5334146109255780636352211e1461094557600080fd5b8063258ef43911610369578063423abb61116102e157806343f51ebb116102b05780634885382a116102955780634885382a1461088f5780634f558e79146108a5578063504ce0e2146108c557600080fd5b806343f51ebb1461085957806343fa2c9c1461087957600080fd5b8063423abb61146107d957806342842e0e146107f957806342966c681461081957806342ec38e21461083957600080fd5b80632b447ff511610338578063341815f61161031d578063341815f614610769578063369b012d1461077f5780633af32abf1461079f57600080fd5b80632b447ff5146107335780632bddccdc1461075357600080fd5b8063258ef4391461069757806327686691146106b75780632a347f61146106ec5780632a55205a146106f457600080fd5b80630ab2b6b9116103fc5780631ef467e1116103cb57806323b872dd116103b057806323b872dd1461064157806324032e9814610661578063254709d31461068157600080fd5b80631ef467e11461060b57806322f4596f1461062b57600080fd5b80630ab2b6b9146105a05780630e21750f146105c057806314066c7c146105e057806318160ddd146105f657600080fd5b806306fdde031161043857806306fdde031461051c5780630764789a1461053e578063081812fc1461055e578063095ea7b31461057e57600080fd5b806301ffc9a71461046a578063029108911461049f57806302964ff1146104c3578063054f7d9c146104fb575b600080fd5b34801561047657600080fd5b5061048a6104853660046137f2565b610d60565b60405190151581526020015b60405180910390f35b3480156104ab57600080fd5b506104b5600d5481565b604051908152602001610496565b3480156104cf57600080fd5b506012546104e3906001600160a01b031681565b6040516001600160a01b039091168152602001610496565b34801561050757600080fd5b5060005461048a90600160a01b900460ff1681565b34801561052857600080fd5b50610531610e42565b6040516104969190613867565b34801561054a57600080fd5b50600f546104e3906001600160a01b031681565b34801561056a57600080fd5b506104e361057936600461387a565b610ed4565b34801561058a57600080fd5b5061059e6105993660046138aa565b610f4f565b005b3480156105ac57600080fd5b506104b56105bb36600461387a565b611036565b3480156105cc57600080fd5b5061059e6105db3660046138d4565b61108c565b3480156105ec57600080fd5b506104b560045481565b34801561060257600080fd5b50600a546104b5565b34801561061757600080fd5b506104b56106263660046138ef565b6110ff565b34801561063757600080fd5b506104b560055481565b34801561064d57600080fd5b5061059e61065c366004613911565b611132565b34801561066d57600080fd5b506011546104e3906001600160a01b031681565b34801561068d57600080fd5b506104b5600c5481565b3480156106a357600080fd5b506104b56106b236600461387a565b6111a4565b3480156106c357600080fd5b506106d76106d236600461387a565b6111bb565b60408051928352602083019190915201610496565b61059e6111e2565b34801561070057600080fd5b5061071461070f3660046138ef565b61138e565b604080516001600160a01b039093168352602083019190915201610496565b34801561073f57600080fd5b5061059e61074e36600461387a565b6113e3565b34801561075f57600080fd5b506104b560095481565b34801561077557600080fd5b506104b5600e5481565b34801561078b57600080fd5b5061059e61079a3660046138d4565b611499565b3480156107ab57600080fd5b5061048a6107ba3660046138d4565b6001600160a01b0316600090815261139e602052604090205460ff1690565b3480156107e557600080fd5b506104b56107f436600461387a565b61150c565b34801561080557600080fd5b5061059e610814366004613911565b611579565b34801561082557600080fd5b5061059e61083436600461387a565b611594565b34801561084557600080fd5b506104b56108543660046138d4565b611684565b34801561086557600080fd5b5061059e6108743660046138ef565b61170b565b34801561088557600080fd5b506104b5600b5481565b34801561089b57600080fd5b506104b560085481565b3480156108b157600080fd5b5061048a6108c036600461387a565b6117d9565b3480156108d157600080fd5b5061059e6108e036600461387a565b6117fb565b3480156108f157600080fd5b5061059e61090036600461387a565b6118bc565b34801561091157600080fd5b506000546104e3906001600160a01b031681565b34801561093157600080fd5b5061059e61094036600461387a565b611952565b34801561095157600080fd5b506104e361096036600461387a565b611a18565b34801561097157600080fd5b5061059e61098036600461387a565b611a72565b34801561099157600080fd5b506104b56109a03660046138d4565b6001600160a01b031660009081526113a0602052604090205490565b3480156109c857600080fd5b506104b560035481565b3480156109de57600080fd5b506104b56109ed36600461387a565b611b1a565b3480156109fe57600080fd5b5061059e611b34565b348015610a1357600080fd5b506104b5610a223660046138ef565b611c13565b348015610a3357600080fd5b5061059e610a423660046138d4565b611e22565b61059e610a5536600461387a565b611e95565b348015610a6657600080fd5b506104b57f000000000000000000000000000000000000000000000000000000000000000081565b348015610a9a57600080fd5b5061059e610aa93660046138d4565b611eef565b348015610aba57600080fd5b50610531611f62565b61059e610ad136600461387a565b611f71565b348015610ae257600080fd5b5061059e610af136600461395d565b612379565b348015610b0257600080fd5b5061059e610b1136600461395d565b61243f565b348015610b2257600080fd5b506104b560065481565b348015610b3857600080fd5b506104b5610b4736600461387a565b600090815261139c602052604090205490565b348015610b6657600080fd5b5061059e610b75366004613987565b6124bc565b348015610b8657600080fd5b5061059e610b95366004613a11565b612546565b348015610ba657600080fd5b5061059e610bb53660046138d4565b6125af565b348015610bc657600080fd5b50610531610bd536600461387a565b612678565b348015610be657600080fd5b506104b5610bf536600461387a565b6127cc565b348015610c0657600080fd5b5061059e610c1536600461387a565b6127ea565b348015610c2657600080fd5b5061059e610c3536600461395d565b612880565b348015610c4657600080fd5b5061059e610c5536600461387a565b612972565b348015610c6657600080fd5b506104e361dead81565b348015610c7c57600080fd5b506104b560075481565b348015610c9257600080fd5b5061048a610ca1366004613abc565b6001600160a01b0391821660009081526113a56020908152604080832093909416825291909152205460ff1690565b348015610cdc57600080fd5b506104b5610ceb36600461387a565b6129c8565b348015610cfc57600080fd5b506010546104e3906001600160a01b031681565b348015610d1c57600080fd5b506104b5600a5481565b348015610d3257600080fd5b5061048a610d413660046138d4565b6001600160a01b0316600090815261139d602052604090205460ff1690565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f80ac58cd000000000000000000000000000000000000000000000000000000007f2a55205a000000000000000000000000000000000000000000000000000000007f5b5e139f000000000000000000000000000000000000000000000000000000006001600160e01b03198616841480610e0a57506001600160e01b0319868116908416145b80610e2157506001600160e01b0319868116908316145b80610e3857506001600160e01b0319868116908216145b9695505050505050565b606060018054610e5190613ae6565b80601f0160208091040260200160405190810160405280929190818152602001828054610e7d90613ae6565b8015610eca5780601f10610e9f57610100808354040283529160200191610eca565b820191906000526020600020905b815481529060010190602001808311610ead57829003601f168201915b5050505050905090565b60008181526113a360205260408120546001600160a01b0316610f325760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b60448201526064015b60405180910390fd5b5060009081526113a460205260409020546001600160a01b031690565b6000610f5a82611a18565b9050806001600160a01b0316836001600160a01b03161415610fbe5760405162461bcd60e51b815260206004820152601960248201527f617070726f76616c20746f2063757272656e74206f776e6572000000000000006044820152606401610f29565b336001600160a01b0382161480610fda5750610fda8133610ca1565b6110265760405162461bcd60e51b815260206004820152601e60248201527f6e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c00006044820152606401610f29565b6110318184846129e2565b505050565b60008181526113a16020526040902054806110875760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b919050565b600f546001600160a01b0316336001600160a01b0316146110dd5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b600061110a83612a3f565b61111382612a9d565b81611121620186a085613b37565b61112b9190613b56565b9392505050565b600080611140335b84612b06565b91509150806111915760405162461bcd60e51b815260206004820152601660248201527f6e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610f29565b61119d82868686612bd5565b5050505050565b6000806111b083611036565b905061112b81611b1a565b60008060006111c9846129c8565b905060006111d685611b1a565b91959194509092505050565b600f546001600160a01b0316336001600160a01b0316146112335760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60006013600a5461127a60408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b6112849190613b84565b61128f906001613b56565b61138981106112a0576112a0613b98565b0154905060005b6112b0826111a4565b600c5460408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a090920190925280519101206112f79190613b84565b1115611381576013600a5461134260408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b61134c9190613b84565b611357906001613b56565b611389811061136857611368613b98565b015490508082141561137957611381565b8091506112a7565b61138a826130a7565b5050565b60008060007f0000000000000000000000000000000000000000000000000000000000000000600b54856113c29190613b37565b6113cc9190613bae565b6012546001600160a01b0316969095509350505050565b600f546001600160a01b0316336001600160a01b0316146114345760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806009541115801561144857506005548111155b6114945760405162461bcd60e51b815260206004820152600d60248201527f696e76616c696420696e646578000000000000000000000000000000000000006044820152606401610f29565b600855565b600f546001600160a01b0316336001600160a01b0316146114ea5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526113a360205260408120546001600160a01b03166115655760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b5060009081526113a2602052604090205490565b61103183838360405180602001604052806000815250612546565b600054600160a01b900460ff16156115e05760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b6000806115ec3361113a565b915091508061163d5760405162461bcd60e51b815260206004820152601660248201527f6e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610f29565b61164782846131f2565b60405183906000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050565b6001600160a01b038116600090815261139e602052604081205460ff16156116ee5760405162461bcd60e51b815260206004820152601160248201527f746f6b656e4f6620756e646566696e65640000000000000000000000000000006044820152606401610f29565b506001600160a01b0316600090815261139f602052604090205490565b600f546001600160a01b0316336001600160a01b03161461175c5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60008281526113a360205260409020546001600160a01b03166117b55760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b6117c281610626846111a4565b60009283526113a160205260409092209190915550565b60008181526113a360205260408120546001600160a01b031615155b92915050565b600f546001600160a01b0316336001600160a01b03161461184c5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b80600e541115801561186b57506118676001620186a0613bc2565b8111155b6118b75760405162461bcd60e51b815260206004820152600f60248201527f696e76616c69642064656e7369747900000000000000000000000000000000006044820152606401610f29565b600655565b600f546001600160a01b0316336001600160a01b03161461190d5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600454811061194d5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b6044820152606401610f29565b600355565b600f546001600160a01b0316336001600160a01b0316146119a35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b7f0000000000000000000000000000000000000000000000000000000000000000811115611a135760405162461bcd60e51b815260206004820152600e60248201527f6d6f7265207468616e20313030250000000000000000000000000000000000006044820152606401610f29565b600b55565b60008181526113a360205260409020546001600160a01b0316806110875760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b600f546001600160a01b0316336001600160a01b031614611ac35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806009541115611b155760405162461bcd60e51b815260206004820152601460248201527f696e76616c696420737570706c7920636f756e740000000000000000000000006044820152606401610f29565b600555565b6000611b29620186a083613b84565b905061108781612a9d565b600f546001600160a01b0316336001600160a01b031614611b855760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b4780611b9057600080fd5b600f546010546001600160a01b0390811691161415611bc257600f54611bbf906001600160a01b031647613341565b50565b601054611be2906001600160a01b0316611bdd600484613bae565b613341565b601154611bfd906001600160a01b0316611bdd600284613bae565b600f54611bbf906001600160a01b031647613341565b33600090815261139e602052604081205460ff16611c735760405162461bcd60e51b815260206004820152601260248201527f696e76616c6964206d73672e73656e64657200000000000000000000000000006044820152606401610f29565b600054600160a01b900460ff1615611cbf5760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b6000611cca84611a18565b9050611cd583611a18565b6001600160a01b0316816001600160a01b031614611d355760405162461bcd60e51b815260206004820152600f60248201527f646973706172617465206f776e657200000000000000000000000000000000006044820152606401610f29565b336001600160a01b03821614611d8d5760405162461bcd60e51b815260206004820152601060248201527f6e6f7420746f6b656e206f776e65722e000000000000000000000000000000006044820152606401610f29565b6001600160a01b03811660009081526113a060205260408120805460019290611db7908490613bc2565b90915550611dc7905084846133e4565b60008181526113a3602052604080822080546001600160a01b03191690555191935083916001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45092915050565b600f546001600160a01b0316336001600160a01b031614611e735760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b600f546001600160a01b0316336001600160a01b031614611ee65760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b611bbf816130a7565b600f546001600160a01b0316336001600160a01b031614611f405760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b606060028054610e5190613ae6565b6003544210158015611f84575060045442105b611fd05760405162461bcd60e51b815260206004820152600d60248201527f73616c65206e6f74206f70656e000000000000000000000000000000000000006044820152606401610f29565b600554600954106120235760405162461bcd60e51b815260206004820152601260248201527f6d617820737570706c79207265616368656400000000000000000000000000006044820152606401610f29565b3233146120725760405162461bcd60e51b815260206004820152601a60248201527f63616e6e6f742075736520637573746f6d20636f6e74726163740000000000006044820152606401610f29565b3360008181526113a06020526040902054600954600d54600c54600f549315159492939192909186916001600160a01b0390911614156120b4575060006120d7565b60085484111580156120c4575084155b156120d757806120d381613bd9565b9150505b6007546120e49082613b37565b3410156121335760405162461bcd60e51b815260206004820152601060248201527f696e73756666696369656e7420455448000000000000000000000000000000006044820152606401610f29565b600e5460006121428883613b56565b90506006548111156121965760405162461bcd60e51b815260206004820152601960248201527f746f74616c206d61782064656e736974792072656163686564000000000000006044820152606401610f29565b600e819055861561221e5733600090815261139e602052604090205460ff16156122025760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742075706461746520776c2064656e7369747900000000000000006044820152606401610f29565b61221461220e33611684565b896135e5565b5050505050505050565b60006005606461226460408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b61226e9190613b84565b1061227a57600161227d565b60025b60ff16905061228c818a6110ff565b60008881526113a160209081526040808320939093556113a3905290812080546001600160a01b03191633179055600a8054916122c883613bf0565b9190505550888510156122dc578894508695505b8660138861138981106122f1576122f1613b98565b0155600087815261139c602052604081208890556123119080338a612bd5565b8661231b81613bf0565b9750508660098190555085600d541461236e57600d869055600c85905560405185815286907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b505050505050505050565b6001600160a01b0382163314156123d25760405162461bcd60e51b815260206004820152601160248201527f617070726f766520746f2063616c6c65720000000000000000000000000000006044820152606401610f29565b3360008181526113a5602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600f546001600160a01b0316336001600160a01b0316146124905760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b6001600160a01b0391909116600090815261139d60205260409020805460ff1916911515919091179055565b600f546001600160a01b0316336001600160a01b03161461250d5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60008054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b612551848484611132565b61255d848484846136b6565b6125a95760405162461bcd60e51b815260206004820152601e60248201527f6e6f6e20455243373231526563656976657220696d706c656d656e74657200006044820152606401610f29565b50505050565b600f546001600160a01b0316336001600160a01b0316146126005760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b662386f26fc1000047106126565760405162461bcd60e51b815260206004820152600a60248201527f6265206361726566756c000000000000000000000000000000000000000000006044820152606401610f29565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526113a360205260409020546060906001600160a01b03166126d45760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b600080548382526113a16020526040909120546001600160a01b039091169063592fa5cc908490612704906129c8565b60008681526113a1602052604090205461271d90611b1a565b600d5460009081526113a1602052604090205461273990611b1a565b600d5488146127478961150c565b6040516001600160e01b031960e089901b16815260048101969096526024860194909452604485019290925260648401521515608483015260a482015260c401600060405180830381865afa1580156127a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117f59190810190613c0b565b600060138261138981106127e2576127e2613b98565b015492915050565b600f546001600160a01b0316336001600160a01b03161461283b5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806003541061287b5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b6044820152606401610f29565b600455565b600f546001600160a01b0316336001600160a01b0316146128d15760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806129465760016128f8836001600160a01b031660009081526113a0602052604090205490565b11156129465760405162461bcd60e51b815260206004820152601660248201527f616464722063616e6e6f742062652072656d6f766564000000000000000000006044820152606401610f29565b6001600160a01b0391909116600090815261139e60205260409020805460ff1916911515919091179055565b600f546001600160a01b0316336001600160a01b0316146129c35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600755565b60006129d7620186a083613bae565b905061108781612a3f565b60008181526113a4602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b80600111158015612a51575060048111155b611bbf5760405162461bcd60e51b815260206004820152601460248201527f636c617373206d757374206265205b312c345d2e0000000000000000000000006044820152606401610f29565b80600111158015612aba5750612ab76001620186a0613bc2565b81105b611bbf5760405162461bcd60e51b815260206004820152601b60248201527f64656e73697479206d757374206265205b312c3130306b2d31292e00000000006044820152606401610f29565b60008181526113a360205260408120546001600160a01b03169081612b615760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b816001600160a01b0316846001600160a01b03161480612b9b575060008381526113a460205260409020546001600160a01b038581169116145b80612bcc57506001600160a01b0380831660009081526113a5602090815260408083209388168352929052205460ff165b90509250929050565b600054600160a01b900460ff1615612c215760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b826001600160a01b0316846001600160a01b031614612c825760405162461bcd60e51b815260206004820152600d60248201527f746f6b656e206e6f74206f776e000000000000000000000000000000000000006044820152606401610f29565b6001600160a01b038216612cd85760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f74207472616e7366657220746f207a65726f2061646472000000006044820152606401610f29565b6001600160a01b038216600090815261139d602052604090205460ff1615612d425760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f74207472616e7366657220746f20626c61636b6c697374000000006044820152606401610f29565b6001600160a01b03821661dead1415612dcf57612d5f84826131f2565b604051819061dead906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4604051819060009061dead907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a46125a9565b612ddb846000836129e2565b80826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4816001600160a01b0316836001600160a01b03161415612e3b576125a9565b6001600160a01b03838116600090815261139e602052604080822054928516825290205460ff91821691168115612ea1576001600160a01b03851660009081526113a060205260408120805460019290612e96908490613bc2565b90915550612ebc9050565b6001600160a01b03851660009081526113a060205260408120555b8015612ef7576001600160a01b03841660009081526113a060205260408120805460019290612eec908490613b56565b90915550612f339050565b6001600160a01b038416600090815261139f6020526040902054612f33576001600160a01b03841660009081526113a060205260409020600190555b8015612f665760008381526113a36020526040902080546001600160a01b0319166001600160a01b03861617905561307f565b6001600160a01b038416600090815261139f602052604090205480612fc55760008481526113a36020908152604080832080546001600160a01b0319166001600160a01b038a16908117909155835261139f909152902084905561307d565b836000612fd283836133e4565b60405190915081906000906001600160a01b038a16907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a482818114156130195750815b60008281526113a36020526040902080546001600160a01b03191690558381146130795760008181526113a36020908152604080832080546001600160a01b0319166001600160a01b038d16908117909155835261139f90915290208190555b5050505b505b8161309f576001600160a01b038516600090815261139f60205260408120555b505050505050565b60008181526113a360205260409020546001600160a01b0316806131015760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b61310b81836131f2565b34156131b6576000816001600160a01b03163460405160006040518083038185875af1925050503d806000811461315e576040519150601f19603f3d011682016040523d82523d6000602084013e613163565b606091505b50509050806131b45760405162461bcd60e51b815260206004820152600f60248201527f7472616e73666572206661696c656400000000000000000000000000000000006044820152606401610f29565b505b60405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6131fe826000836129e2565b60008181526113a1602052604090205461321790611b1a565b600e60008282546132289190613bc2565b90915550506001600160a01b038216600090815261139f602090815260408083208390558383526113a3825280832080546001600160a01b03191690556113a1825280832083905561139c909152812054600a54909190601390611389811061329357613293613b98565b015490508060138361138981106132ac576132ac613b98565b0155600081815261139c60205260408120839055600a8054916132ce83613bd9565b90915550506001600160a01b03841660009081526113a0602052604081208054600192906132fd908490613bc2565b909155505060405160008082529084907f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef906020015b60405180910390a350505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461338e576040519150601f19603f3d011682016040523d82523d6000602084013e613393565b606091505b50509050806110315760405162461bcd60e51b815260206004820152600f60248201527f7472616e73666572206661696c656400000000000000000000000000000000006044820152606401610f29565b6000818314156134365760405162461bcd60e51b815260206004820152601160248201527f6964656e746963616c20746f6b656e49640000000000000000000000000000006044820152606401610f29565b60008381526113a1602052604081205461344f90611b1a565b60008481526113a160205260408120549192509061346c90611b1a565b9050818186868284106134855750839250849150869050875b60008181526113a16020526040812080548692906134a4908490613b56565b90915550600090506134b68585613b56565b9050600c5481111561350257600d829055600c81905560405181815282907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b60008281526113a26020526040812080549161351d83613bf0565b909155505060008381526113a16020908152604080832083905561139c909152812054600a54909190601390611389811061355a5761355a613b98565b0154905080601383611389811061357357613573613b98565b0155600081815261139c60205260408120839055600a80549161359583613bd9565b919050555083857f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef856040516135cd91815260200190565b60405180910390a350929a9950505050505050505050565b60008281526113a160205260408120546135fe90611b1a565b9050816113a1600085815260200190815260200160002060008282546136249190613b56565b90915550600090506136368383613b56565b9050600c5481111561368257600d849055600c81905560405181815284907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b8360007f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef8360405161333391815260200190565b6000833b156137d057604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906136f1903390899088908890600401613c82565b6020604051808303816000875af192505050801561372c575060408051601f3d908101601f1916820190925261372991810190613cb4565b60015b6137b6573d80801561375a576040519150601f19603f3d011682016040523d82523d6000602084013e61375f565b606091505b5080516137ae5760405162461bcd60e51b815260206004820152601e60248201527f6e6f6e20455243373231526563656976657220696d706c656d656e74657200006044820152606401610f29565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506137d4565b5060015b949350505050565b6001600160e01b031981168114611bbf57600080fd5b60006020828403121561380457600080fd5b813561112b816137dc565b60005b8381101561382a578181015183820152602001613812565b838111156125a95750506000910152565b6000815180845261385381602086016020860161380f565b601f01601f19169290920160200192915050565b60208152600061112b602083018461383b565b60006020828403121561388c57600080fd5b5035919050565b80356001600160a01b038116811461108757600080fd5b600080604083850312156138bd57600080fd5b6138c683613893565b946020939093013593505050565b6000602082840312156138e657600080fd5b61112b82613893565b6000806040838503121561390257600080fd5b50508035926020909101359150565b60008060006060848603121561392657600080fd5b61392f84613893565b925061393d60208501613893565b9150604084013590509250925092565b8035801515811461108757600080fd5b6000806040838503121561397057600080fd5b61397983613893565b9150612bcc6020840161394d565b60006020828403121561399957600080fd5b61112b8261394d565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156139e1576139e16139a2565b604052919050565b600067ffffffffffffffff821115613a0357613a036139a2565b50601f01601f191660200190565b60008060008060808587031215613a2757600080fd5b613a3085613893565b9350613a3e60208601613893565b925060408501359150606085013567ffffffffffffffff811115613a6157600080fd5b8501601f81018713613a7257600080fd5b8035613a85613a80826139e9565b6139b8565b818152886020838501011115613a9a57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060408385031215613acf57600080fd5b613ad883613893565b9150612bcc60208401613893565b600181811c90821680613afa57607f821691505b60208210811415613b1b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613b5157613b51613b21565b500290565b60008219821115613b6957613b69613b21565b500190565b634e487b7160e01b600052601260045260246000fd5b600082613b9357613b93613b6e565b500690565b634e487b7160e01b600052603260045260246000fd5b600082613bbd57613bbd613b6e565b500490565b600082821015613bd457613bd4613b21565b500390565b600081613be857613be8613b21565b506000190190565b6000600019821415613c0457613c04613b21565b5060010190565b600060208284031215613c1d57600080fd5b815167ffffffffffffffff811115613c3457600080fd5b8201601f81018413613c4557600080fd5b8051613c53613a80826139e9565b818152856020838501011115613c6857600080fd5b613c7982602083016020860161380f565b95945050505050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152610e38608083018461383b565b600060208284031215613cc657600080fd5b815161112b816137dc56fe6d73672e73656e646572206973206e6f742068616b0000000000000000000000a26469706673582212201e111a1df4a28d4f1931a31bf43916d3927fcd4089eb14d334200a080914f62864736f6c634300080a00330000000000000000000000003569fbc5b9cb5e21a18b632c97c32f7a296734f5000000000000000000000000405937f8ad695b20bb2eb4630c7bc9bae23326d8000000000000000000000000f80a1479f144e3a2f74a77ca9c07964b7349c4f8

Deployed Bytecode

0x6080604052600436106104655760003560e01c8063525f8a5c11610243578063a755516011610143578063dbf65de0116100bb578063e985e9c51161008a578063ec259d171161006f578063ec259d1714610cf0578063fb1fac1814610d10578063fe575a8714610d2657600080fd5b8063e985e9c514610c86578063eafe706e14610cd057600080fd5b8063dbf65de014610c1a578063dc1b732814610c3a578063dcfb383314610c5a578063dde502d114610c7057600080fd5b8063b88d4fde11610112578063c87b56dd116100f7578063c87b56dd14610bba578063cbd14a7d14610bda578063d132391a14610bfa57600080fd5b8063b88d4fde14610b7a578063b8d4a4aa14610b9a57600080fd5b8063a755516014610af6578063a819e4e414610b16578063a8a07b3614610b2c578063b5bf15e514610b5a57600080fd5b8063853828b6116101d65780639121ac0d116101a557806395d89b411161018a57806395d89b4114610aae578063a0712d6814610ac3578063a22cb46514610ad657600080fd5b80639121ac0d14610a5a5780639377736914610a8e57600080fd5b8063853828b6146109f25780638a50fecb14610a075780638dc251e314610a2757806390b5098814610a4757600080fd5b80636f8b44b0116102125780636f8b44b01461096557806370a082311461098557806375a99b9f146109bc57806378907bf7146109d257600080fd5b8063525f8a5c146108e557806355d5f96314610905578063629a5334146109255780636352211e1461094557600080fd5b8063258ef43911610369578063423abb61116102e157806343f51ebb116102b05780634885382a116102955780634885382a1461088f5780634f558e79146108a5578063504ce0e2146108c557600080fd5b806343f51ebb1461085957806343fa2c9c1461087957600080fd5b8063423abb61146107d957806342842e0e146107f957806342966c681461081957806342ec38e21461083957600080fd5b80632b447ff511610338578063341815f61161031d578063341815f614610769578063369b012d1461077f5780633af32abf1461079f57600080fd5b80632b447ff5146107335780632bddccdc1461075357600080fd5b8063258ef4391461069757806327686691146106b75780632a347f61146106ec5780632a55205a146106f457600080fd5b80630ab2b6b9116103fc5780631ef467e1116103cb57806323b872dd116103b057806323b872dd1461064157806324032e9814610661578063254709d31461068157600080fd5b80631ef467e11461060b57806322f4596f1461062b57600080fd5b80630ab2b6b9146105a05780630e21750f146105c057806314066c7c146105e057806318160ddd146105f657600080fd5b806306fdde031161043857806306fdde031461051c5780630764789a1461053e578063081812fc1461055e578063095ea7b31461057e57600080fd5b806301ffc9a71461046a578063029108911461049f57806302964ff1146104c3578063054f7d9c146104fb575b600080fd5b34801561047657600080fd5b5061048a6104853660046137f2565b610d60565b60405190151581526020015b60405180910390f35b3480156104ab57600080fd5b506104b5600d5481565b604051908152602001610496565b3480156104cf57600080fd5b506012546104e3906001600160a01b031681565b6040516001600160a01b039091168152602001610496565b34801561050757600080fd5b5060005461048a90600160a01b900460ff1681565b34801561052857600080fd5b50610531610e42565b6040516104969190613867565b34801561054a57600080fd5b50600f546104e3906001600160a01b031681565b34801561056a57600080fd5b506104e361057936600461387a565b610ed4565b34801561058a57600080fd5b5061059e6105993660046138aa565b610f4f565b005b3480156105ac57600080fd5b506104b56105bb36600461387a565b611036565b3480156105cc57600080fd5b5061059e6105db3660046138d4565b61108c565b3480156105ec57600080fd5b506104b560045481565b34801561060257600080fd5b50600a546104b5565b34801561061757600080fd5b506104b56106263660046138ef565b6110ff565b34801561063757600080fd5b506104b560055481565b34801561064d57600080fd5b5061059e61065c366004613911565b611132565b34801561066d57600080fd5b506011546104e3906001600160a01b031681565b34801561068d57600080fd5b506104b5600c5481565b3480156106a357600080fd5b506104b56106b236600461387a565b6111a4565b3480156106c357600080fd5b506106d76106d236600461387a565b6111bb565b60408051928352602083019190915201610496565b61059e6111e2565b34801561070057600080fd5b5061071461070f3660046138ef565b61138e565b604080516001600160a01b039093168352602083019190915201610496565b34801561073f57600080fd5b5061059e61074e36600461387a565b6113e3565b34801561075f57600080fd5b506104b560095481565b34801561077557600080fd5b506104b5600e5481565b34801561078b57600080fd5b5061059e61079a3660046138d4565b611499565b3480156107ab57600080fd5b5061048a6107ba3660046138d4565b6001600160a01b0316600090815261139e602052604090205460ff1690565b3480156107e557600080fd5b506104b56107f436600461387a565b61150c565b34801561080557600080fd5b5061059e610814366004613911565b611579565b34801561082557600080fd5b5061059e61083436600461387a565b611594565b34801561084557600080fd5b506104b56108543660046138d4565b611684565b34801561086557600080fd5b5061059e6108743660046138ef565b61170b565b34801561088557600080fd5b506104b5600b5481565b34801561089b57600080fd5b506104b560085481565b3480156108b157600080fd5b5061048a6108c036600461387a565b6117d9565b3480156108d157600080fd5b5061059e6108e036600461387a565b6117fb565b3480156108f157600080fd5b5061059e61090036600461387a565b6118bc565b34801561091157600080fd5b506000546104e3906001600160a01b031681565b34801561093157600080fd5b5061059e61094036600461387a565b611952565b34801561095157600080fd5b506104e361096036600461387a565b611a18565b34801561097157600080fd5b5061059e61098036600461387a565b611a72565b34801561099157600080fd5b506104b56109a03660046138d4565b6001600160a01b031660009081526113a0602052604090205490565b3480156109c857600080fd5b506104b560035481565b3480156109de57600080fd5b506104b56109ed36600461387a565b611b1a565b3480156109fe57600080fd5b5061059e611b34565b348015610a1357600080fd5b506104b5610a223660046138ef565b611c13565b348015610a3357600080fd5b5061059e610a423660046138d4565b611e22565b61059e610a5536600461387a565b611e95565b348015610a6657600080fd5b506104b57f000000000000000000000000000000000000000000000000000000000000271081565b348015610a9a57600080fd5b5061059e610aa93660046138d4565b611eef565b348015610aba57600080fd5b50610531611f62565b61059e610ad136600461387a565b611f71565b348015610ae257600080fd5b5061059e610af136600461395d565b612379565b348015610b0257600080fd5b5061059e610b1136600461395d565b61243f565b348015610b2257600080fd5b506104b560065481565b348015610b3857600080fd5b506104b5610b4736600461387a565b600090815261139c602052604090205490565b348015610b6657600080fd5b5061059e610b75366004613987565b6124bc565b348015610b8657600080fd5b5061059e610b95366004613a11565b612546565b348015610ba657600080fd5b5061059e610bb53660046138d4565b6125af565b348015610bc657600080fd5b50610531610bd536600461387a565b612678565b348015610be657600080fd5b506104b5610bf536600461387a565b6127cc565b348015610c0657600080fd5b5061059e610c1536600461387a565b6127ea565b348015610c2657600080fd5b5061059e610c3536600461395d565b612880565b348015610c4657600080fd5b5061059e610c5536600461387a565b612972565b348015610c6657600080fd5b506104e361dead81565b348015610c7c57600080fd5b506104b560075481565b348015610c9257600080fd5b5061048a610ca1366004613abc565b6001600160a01b0391821660009081526113a56020908152604080832093909416825291909152205460ff1690565b348015610cdc57600080fd5b506104b5610ceb36600461387a565b6129c8565b348015610cfc57600080fd5b506010546104e3906001600160a01b031681565b348015610d1c57600080fd5b506104b5600a5481565b348015610d3257600080fd5b5061048a610d413660046138d4565b6001600160a01b0316600090815261139d602052604090205460ff1690565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007f80ac58cd000000000000000000000000000000000000000000000000000000007f2a55205a000000000000000000000000000000000000000000000000000000007f5b5e139f000000000000000000000000000000000000000000000000000000006001600160e01b03198616841480610e0a57506001600160e01b0319868116908416145b80610e2157506001600160e01b0319868116908316145b80610e3857506001600160e01b0319868116908216145b9695505050505050565b606060018054610e5190613ae6565b80601f0160208091040260200160405190810160405280929190818152602001828054610e7d90613ae6565b8015610eca5780601f10610e9f57610100808354040283529160200191610eca565b820191906000526020600020905b815481529060010190602001808311610ead57829003601f168201915b5050505050905090565b60008181526113a360205260408120546001600160a01b0316610f325760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b60448201526064015b60405180910390fd5b5060009081526113a460205260409020546001600160a01b031690565b6000610f5a82611a18565b9050806001600160a01b0316836001600160a01b03161415610fbe5760405162461bcd60e51b815260206004820152601960248201527f617070726f76616c20746f2063757272656e74206f776e6572000000000000006044820152606401610f29565b336001600160a01b0382161480610fda5750610fda8133610ca1565b6110265760405162461bcd60e51b815260206004820152601e60248201527f6e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c00006044820152606401610f29565b6110318184846129e2565b505050565b60008181526113a16020526040902054806110875760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b919050565b600f546001600160a01b0316336001600160a01b0316146110dd5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b600061110a83612a3f565b61111382612a9d565b81611121620186a085613b37565b61112b9190613b56565b9392505050565b600080611140335b84612b06565b91509150806111915760405162461bcd60e51b815260206004820152601660248201527f6e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610f29565b61119d82868686612bd5565b5050505050565b6000806111b083611036565b905061112b81611b1a565b60008060006111c9846129c8565b905060006111d685611b1a565b91959194509092505050565b600f546001600160a01b0316336001600160a01b0316146112335760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60006013600a5461127a60408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b6112849190613b84565b61128f906001613b56565b61138981106112a0576112a0613b98565b0154905060005b6112b0826111a4565b600c5460408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a090920190925280519101206112f79190613b84565b1115611381576013600a5461134260408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b61134c9190613b84565b611357906001613b56565b611389811061136857611368613b98565b015490508082141561137957611381565b8091506112a7565b61138a826130a7565b5050565b60008060007f0000000000000000000000000000000000000000000000000000000000002710600b54856113c29190613b37565b6113cc9190613bae565b6012546001600160a01b0316969095509350505050565b600f546001600160a01b0316336001600160a01b0316146114345760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806009541115801561144857506005548111155b6114945760405162461bcd60e51b815260206004820152600d60248201527f696e76616c696420696e646578000000000000000000000000000000000000006044820152606401610f29565b600855565b600f546001600160a01b0316336001600160a01b0316146114ea5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526113a360205260408120546001600160a01b03166115655760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b5060009081526113a2602052604090205490565b61103183838360405180602001604052806000815250612546565b600054600160a01b900460ff16156115e05760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b6000806115ec3361113a565b915091508061163d5760405162461bcd60e51b815260206004820152601660248201527f6e6f74206f776e6572206e6f7220617070726f766564000000000000000000006044820152606401610f29565b61164782846131f2565b60405183906000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a4505050565b6001600160a01b038116600090815261139e602052604081205460ff16156116ee5760405162461bcd60e51b815260206004820152601160248201527f746f6b656e4f6620756e646566696e65640000000000000000000000000000006044820152606401610f29565b506001600160a01b0316600090815261139f602052604090205490565b600f546001600160a01b0316336001600160a01b03161461175c5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60008281526113a360205260409020546001600160a01b03166117b55760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b6117c281610626846111a4565b60009283526113a160205260409092209190915550565b60008181526113a360205260408120546001600160a01b031615155b92915050565b600f546001600160a01b0316336001600160a01b03161461184c5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b80600e541115801561186b57506118676001620186a0613bc2565b8111155b6118b75760405162461bcd60e51b815260206004820152600f60248201527f696e76616c69642064656e7369747900000000000000000000000000000000006044820152606401610f29565b600655565b600f546001600160a01b0316336001600160a01b03161461190d5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600454811061194d5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b6044820152606401610f29565b600355565b600f546001600160a01b0316336001600160a01b0316146119a35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b7f0000000000000000000000000000000000000000000000000000000000002710811115611a135760405162461bcd60e51b815260206004820152600e60248201527f6d6f7265207468616e20313030250000000000000000000000000000000000006044820152606401610f29565b600b55565b60008181526113a360205260409020546001600160a01b0316806110875760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b600f546001600160a01b0316336001600160a01b031614611ac35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806009541115611b155760405162461bcd60e51b815260206004820152601460248201527f696e76616c696420737570706c7920636f756e740000000000000000000000006044820152606401610f29565b600555565b6000611b29620186a083613b84565b905061108781612a9d565b600f546001600160a01b0316336001600160a01b031614611b855760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b4780611b9057600080fd5b600f546010546001600160a01b0390811691161415611bc257600f54611bbf906001600160a01b031647613341565b50565b601054611be2906001600160a01b0316611bdd600484613bae565b613341565b601154611bfd906001600160a01b0316611bdd600284613bae565b600f54611bbf906001600160a01b031647613341565b33600090815261139e602052604081205460ff16611c735760405162461bcd60e51b815260206004820152601260248201527f696e76616c6964206d73672e73656e64657200000000000000000000000000006044820152606401610f29565b600054600160a01b900460ff1615611cbf5760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b6000611cca84611a18565b9050611cd583611a18565b6001600160a01b0316816001600160a01b031614611d355760405162461bcd60e51b815260206004820152600f60248201527f646973706172617465206f776e657200000000000000000000000000000000006044820152606401610f29565b336001600160a01b03821614611d8d5760405162461bcd60e51b815260206004820152601060248201527f6e6f7420746f6b656e206f776e65722e000000000000000000000000000000006044820152606401610f29565b6001600160a01b03811660009081526113a060205260408120805460019290611db7908490613bc2565b90915550611dc7905084846133e4565b60008181526113a3602052604080822080546001600160a01b03191690555191935083916001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45092915050565b600f546001600160a01b0316336001600160a01b031614611e735760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b601280546001600160a01b0319166001600160a01b0392909216919091179055565b600f546001600160a01b0316336001600160a01b031614611ee65760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b611bbf816130a7565b600f546001600160a01b0316336001600160a01b031614611f405760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b606060028054610e5190613ae6565b6003544210158015611f84575060045442105b611fd05760405162461bcd60e51b815260206004820152600d60248201527f73616c65206e6f74206f70656e000000000000000000000000000000000000006044820152606401610f29565b600554600954106120235760405162461bcd60e51b815260206004820152601260248201527f6d617820737570706c79207265616368656400000000000000000000000000006044820152606401610f29565b3233146120725760405162461bcd60e51b815260206004820152601a60248201527f63616e6e6f742075736520637573746f6d20636f6e74726163740000000000006044820152606401610f29565b3360008181526113a06020526040902054600954600d54600c54600f549315159492939192909186916001600160a01b0390911614156120b4575060006120d7565b60085484111580156120c4575084155b156120d757806120d381613bd9565b9150505b6007546120e49082613b37565b3410156121335760405162461bcd60e51b815260206004820152601060248201527f696e73756666696369656e7420455448000000000000000000000000000000006044820152606401610f29565b600e5460006121428883613b56565b90506006548111156121965760405162461bcd60e51b815260206004820152601960248201527f746f74616c206d61782064656e736974792072656163686564000000000000006044820152606401610f29565b600e819055861561221e5733600090815261139e602052604090205460ff16156122025760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742075706461746520776c2064656e7369747900000000000000006044820152606401610f29565b61221461220e33611684565b896135e5565b5050505050505050565b60006005606461226460408051426020808301919091524482840152416060830152336080808401919091528351808403909101815260a0909201909252805191012090565b61226e9190613b84565b1061227a57600161227d565b60025b60ff16905061228c818a6110ff565b60008881526113a160209081526040808320939093556113a3905290812080546001600160a01b03191633179055600a8054916122c883613bf0565b9190505550888510156122dc578894508695505b8660138861138981106122f1576122f1613b98565b0155600087815261139c602052604081208890556123119080338a612bd5565b8661231b81613bf0565b9750508660098190555085600d541461236e57600d869055600c85905560405185815286907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b505050505050505050565b6001600160a01b0382163314156123d25760405162461bcd60e51b815260206004820152601160248201527f617070726f766520746f2063616c6c65720000000000000000000000000000006044820152606401610f29565b3360008181526113a5602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600f546001600160a01b0316336001600160a01b0316146124905760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b6001600160a01b0391909116600090815261139d60205260409020805460ff1916911515919091179055565b600f546001600160a01b0316336001600160a01b03161461250d5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b60008054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b612551848484611132565b61255d848484846136b6565b6125a95760405162461bcd60e51b815260206004820152601e60248201527f6e6f6e20455243373231526563656976657220696d706c656d656e74657200006044820152606401610f29565b50505050565b600f546001600160a01b0316336001600160a01b0316146126005760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b662386f26fc1000047106126565760405162461bcd60e51b815260206004820152600a60248201527f6265206361726566756c000000000000000000000000000000000000000000006044820152606401610f29565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b60008181526113a360205260409020546060906001600160a01b03166126d45760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b600080548382526113a16020526040909120546001600160a01b039091169063592fa5cc908490612704906129c8565b60008681526113a1602052604090205461271d90611b1a565b600d5460009081526113a1602052604090205461273990611b1a565b600d5488146127478961150c565b6040516001600160e01b031960e089901b16815260048101969096526024860194909452604485019290925260648401521515608483015260a482015260c401600060405180830381865afa1580156127a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117f59190810190613c0b565b600060138261138981106127e2576127e2613b98565b015492915050565b600f546001600160a01b0316336001600160a01b03161461283b5760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806003541061287b5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c69642074696d6560a01b6044820152606401610f29565b600455565b600f546001600160a01b0316336001600160a01b0316146128d15760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b806129465760016128f8836001600160a01b031660009081526113a0602052604090205490565b11156129465760405162461bcd60e51b815260206004820152601660248201527f616464722063616e6e6f742062652072656d6f766564000000000000000000006044820152606401610f29565b6001600160a01b0391909116600090815261139e60205260409020805460ff1916911515919091179055565b600f546001600160a01b0316336001600160a01b0316146129c35760405162461bcd60e51b81526020600482015260156024820152600080516020613cd28339815191526044820152606401610f29565b600755565b60006129d7620186a083613bae565b905061108781612a3f565b60008181526113a4602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b80600111158015612a51575060048111155b611bbf5760405162461bcd60e51b815260206004820152601460248201527f636c617373206d757374206265205b312c345d2e0000000000000000000000006044820152606401610f29565b80600111158015612aba5750612ab76001620186a0613bc2565b81105b611bbf5760405162461bcd60e51b815260206004820152601b60248201527f64656e73697479206d757374206265205b312c3130306b2d31292e00000000006044820152606401610f29565b60008181526113a360205260408120546001600160a01b03169081612b615760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b816001600160a01b0316846001600160a01b03161480612b9b575060008381526113a460205260409020546001600160a01b038581169116145b80612bcc57506001600160a01b0380831660009081526113a5602090815260408083209388168352929052205460ff165b90509250929050565b600054600160a01b900460ff1615612c215760405162461bcd60e51b815260206004820152600f60248201526e3a3930b739b332b910333937bd32b760891b6044820152606401610f29565b826001600160a01b0316846001600160a01b031614612c825760405162461bcd60e51b815260206004820152600d60248201527f746f6b656e206e6f74206f776e000000000000000000000000000000000000006044820152606401610f29565b6001600160a01b038216612cd85760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f74207472616e7366657220746f207a65726f2061646472000000006044820152606401610f29565b6001600160a01b038216600090815261139d602052604090205460ff1615612d425760405162461bcd60e51b815260206004820152601c60248201527f63616e6e6f74207472616e7366657220746f20626c61636b6c697374000000006044820152606401610f29565b6001600160a01b03821661dead1415612dcf57612d5f84826131f2565b604051819061dead906001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90600090a4604051819060009061dead907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a46125a9565b612ddb846000836129e2565b80826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4816001600160a01b0316836001600160a01b03161415612e3b576125a9565b6001600160a01b03838116600090815261139e602052604080822054928516825290205460ff91821691168115612ea1576001600160a01b03851660009081526113a060205260408120805460019290612e96908490613bc2565b90915550612ebc9050565b6001600160a01b03851660009081526113a060205260408120555b8015612ef7576001600160a01b03841660009081526113a060205260408120805460019290612eec908490613b56565b90915550612f339050565b6001600160a01b038416600090815261139f6020526040902054612f33576001600160a01b03841660009081526113a060205260409020600190555b8015612f665760008381526113a36020526040902080546001600160a01b0319166001600160a01b03861617905561307f565b6001600160a01b038416600090815261139f602052604090205480612fc55760008481526113a36020908152604080832080546001600160a01b0319166001600160a01b038a16908117909155835261139f909152902084905561307d565b836000612fd283836133e4565b60405190915081906000906001600160a01b038a16907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a482818114156130195750815b60008281526113a36020526040902080546001600160a01b03191690558381146130795760008181526113a36020908152604080832080546001600160a01b0319166001600160a01b038d16908117909155835261139f90915290208190555b5050505b505b8161309f576001600160a01b038516600090815261139f60205260408120555b505050505050565b60008181526113a360205260409020546001600160a01b0316806131015760405162461bcd60e51b81526020600482015260116024820152703737b732bc34b9ba32b73a103a37b5b2b760791b6044820152606401610f29565b61310b81836131f2565b34156131b6576000816001600160a01b03163460405160006040518083038185875af1925050503d806000811461315e576040519150601f19603f3d011682016040523d82523d6000602084013e613163565b606091505b50509050806131b45760405162461bcd60e51b815260206004820152600f60248201527f7472616e73666572206661696c656400000000000000000000000000000000006044820152606401610f29565b505b60405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6131fe826000836129e2565b60008181526113a1602052604090205461321790611b1a565b600e60008282546132289190613bc2565b90915550506001600160a01b038216600090815261139f602090815260408083208390558383526113a3825280832080546001600160a01b03191690556113a1825280832083905561139c909152812054600a54909190601390611389811061329357613293613b98565b015490508060138361138981106132ac576132ac613b98565b0155600081815261139c60205260408120839055600a8054916132ce83613bd9565b90915550506001600160a01b03841660009081526113a0602052604081208054600192906132fd908490613bc2565b909155505060405160008082529084907f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef906020015b60405180910390a350505050565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461338e576040519150601f19603f3d011682016040523d82523d6000602084013e613393565b606091505b50509050806110315760405162461bcd60e51b815260206004820152600f60248201527f7472616e73666572206661696c656400000000000000000000000000000000006044820152606401610f29565b6000818314156134365760405162461bcd60e51b815260206004820152601160248201527f6964656e746963616c20746f6b656e49640000000000000000000000000000006044820152606401610f29565b60008381526113a1602052604081205461344f90611b1a565b60008481526113a160205260408120549192509061346c90611b1a565b9050818186868284106134855750839250849150869050875b60008181526113a16020526040812080548692906134a4908490613b56565b90915550600090506134b68585613b56565b9050600c5481111561350257600d829055600c81905560405181815282907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b60008281526113a26020526040812080549161351d83613bf0565b909155505060008381526113a16020908152604080832083905561139c909152812054600a54909190601390611389811061355a5761355a613b98565b0154905080601383611389811061357357613573613b98565b0155600081815261139c60205260408120839055600a80549161359583613bd9565b919050555083857f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef856040516135cd91815260200190565b60405180910390a350929a9950505050505050505050565b60008281526113a160205260408120546135fe90611b1a565b9050816113a1600085815260200190815260200160002060008282546136249190613b56565b90915550600090506136368383613b56565b9050600c5481111561368257600d849055600c81905560405181815284907fcc5cee89197deb1a6a7aec5bb542c349613219ebea24b0cd94488f5d834480749060200160405180910390a25b8360007f227e3bf37914765060d7c79fc14bc5619d5d06e9e6c55982c7fba76536e86eef8360405161333391815260200190565b6000833b156137d057604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906136f1903390899088908890600401613c82565b6020604051808303816000875af192505050801561372c575060408051601f3d908101601f1916820190925261372991810190613cb4565b60015b6137b6573d80801561375a576040519150601f19603f3d011682016040523d82523d6000602084013e61375f565b606091505b5080516137ae5760405162461bcd60e51b815260206004820152601e60248201527f6e6f6e20455243373231526563656976657220696d706c656d656e74657200006044820152606401610f29565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506137d4565b5060015b949350505050565b6001600160e01b031981168114611bbf57600080fd5b60006020828403121561380457600080fd5b813561112b816137dc565b60005b8381101561382a578181015183820152602001613812565b838111156125a95750506000910152565b6000815180845261385381602086016020860161380f565b601f01601f19169290920160200192915050565b60208152600061112b602083018461383b565b60006020828403121561388c57600080fd5b5035919050565b80356001600160a01b038116811461108757600080fd5b600080604083850312156138bd57600080fd5b6138c683613893565b946020939093013593505050565b6000602082840312156138e657600080fd5b61112b82613893565b6000806040838503121561390257600080fd5b50508035926020909101359150565b60008060006060848603121561392657600080fd5b61392f84613893565b925061393d60208501613893565b9150604084013590509250925092565b8035801515811461108757600080fd5b6000806040838503121561397057600080fd5b61397983613893565b9150612bcc6020840161394d565b60006020828403121561399957600080fd5b61112b8261394d565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156139e1576139e16139a2565b604052919050565b600067ffffffffffffffff821115613a0357613a036139a2565b50601f01601f191660200190565b60008060008060808587031215613a2757600080fd5b613a3085613893565b9350613a3e60208601613893565b925060408501359150606085013567ffffffffffffffff811115613a6157600080fd5b8501601f81018713613a7257600080fd5b8035613a85613a80826139e9565b6139b8565b818152886020838501011115613a9a57600080fd5b8160208401602083013760006020838301015280935050505092959194509250565b60008060408385031215613acf57600080fd5b613ad883613893565b9150612bcc60208401613893565b600181811c90821680613afa57607f821691505b60208210811415613b1b57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613b5157613b51613b21565b500290565b60008219821115613b6957613b69613b21565b500190565b634e487b7160e01b600052601260045260246000fd5b600082613b9357613b93613b6e565b500690565b634e487b7160e01b600052603260045260246000fd5b600082613bbd57613bbd613b6e565b500490565b600082821015613bd457613bd4613b21565b500390565b600081613be857613be8613b21565b506000190190565b6000600019821415613c0457613c04613b21565b5060010190565b600060208284031215613c1d57600080fd5b815167ffffffffffffffff811115613c3457600080fd5b8201601f81018413613c4557600080fd5b8051613c53613a80826139e9565b818152856020838501011115613c6857600080fd5b613c7982602083016020860161380f565b95945050505050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152610e38608083018461383b565b600060208284031215613cc657600080fd5b815161112b816137dc56fe6d73672e73656e646572206973206e6f742068616b0000000000000000000000a26469706673582212201e111a1df4a28d4f1931a31bf43916d3927fcd4089eb14d334200a080914f62864736f6c634300080a0033

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

0000000000000000000000003569fbc5b9cb5e21a18b632c97c32f7a296734f5000000000000000000000000405937f8ad695b20bb2eb4630c7bc9bae23326d8000000000000000000000000f80a1479f144e3a2f74a77ca9c07964b7349c4f8

-----Decoded View---------------
Arg [0] : metadataGenerator_ (address): 0x3569FBC5B9cB5E21a18B632c97C32F7a296734F5
Arg [1] : collab_ (address): 0x405937f8AD695b20bB2eB4630c7bC9BaE23326d8
Arg [2] : fund_ (address): 0xf80A1479f144e3a2F74A77ca9C07964B7349c4f8

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000003569fbc5b9cb5e21a18b632c97c32f7a296734f5
Arg [1] : 000000000000000000000000405937f8ad695b20bb2eb4630c7bc9bae23326d8
Arg [2] : 000000000000000000000000f80a1479f144e3a2f74a77ca9c07964b7349c4f8


Deployed Bytecode Sourcemap

53636:29697:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81927:435;;;;;;;;;;-1:-1:-1;81927:435:0;;;;;:::i;:::-;;:::i;:::-;;;611:14:1;;604:22;586:41;;574:2;559:18;81927:435:0;;;;;;;;54683:23;;;;;;;;;;;;;;;;;;;784:25:1;;;772:2;757:18;54683:23:0;638:177:1;54834:24:0;;;;;;;;;;-1:-1:-1;54834:24:0;;;;-1:-1:-1;;;;;54834:24:0;;;;;;-1:-1:-1;;;;;984:55:1;;;966:74;;954:2;939:18;54834:24:0;820:226:1;53740:18:0;;;;;;;;;;-1:-1:-1;53740:18:0;;;;-1:-1:-1;;;53740:18:0;;;;;;58402:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;54752:19::-;;;;;;;;;;-1:-1:-1;54752:19:0;;;;-1:-1:-1;;;;;54752:19:0;;;77302:199;;;;;;;;;;-1:-1:-1;77302:199:0;;;;;:::i;:::-;;:::i;76754:361::-;;;;;;;;;;-1:-1:-1;76754:361:0;;;;;:::i;:::-;;:::i;:::-;;76359:175;;;;;;;;;;-1:-1:-1;76359:175:0;;;;;:::i;:::-;;:::i;68584:83::-;;;;;;;;;;-1:-1:-1;68584:83:0;;;;;:::i;:::-;;:::i;54271:40::-;;;;;;;;;;;;;;;;58623:90;;;;;;;;;;-1:-1:-1;58694:11:0;;58623:90;;79266:229;;;;;;;;;;-1:-1:-1;79266:229:0;;;;;:::i;:::-;;:::i;54320:32::-;;;;;;;;;;;;;;;;75746:300;;;;;;;;;;-1:-1:-1;75746:300:0;;;;;:::i;:::-;;:::i;54807:20::-;;;;;;;;;;-1:-1:-1;54807:20:0;;;;-1:-1:-1;;;;;54807:20:0;;;54646:28;;;;;;;;;;;;;;;;76185:166;;;;;;;;;;-1:-1:-1;76185:166:0;;;;;:::i;:::-;;:::i;79503:221::-;;;;;;;;;;-1:-1:-1;79503:221:0;;;;;:::i;:::-;;:::i;:::-;;;;3398:25:1;;;3454:2;3439:18;;3432:34;;;;3371:18;79503:221:0;3224:248:1;74817:489:0;;;:::i;68101:236::-;;;;;;;;;;-1:-1:-1;68101:236:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3669:55:1;;;3651:74;;3756:2;3741:18;;3734:34;;;;3624:18;68101:236:0;3477:297:1;69519:175:0;;;;;;;;;;-1:-1:-1;69519:175:0;;;;;:::i;:::-;;:::i;54485:26::-;;;;;;;;;;;;;;;;54715:28;;;;;;;;;;;;;;;;68485:91;;;;;;;;;;-1:-1:-1;68485:91:0;;;;;:::i;:::-;;:::i;70447:121::-;;;;;;;;;;-1:-1:-1;70447:121:0;;;;;:::i;:::-;-1:-1:-1;;;;;70533:27:0;70509:4;70533:27;;;:17;:27;;;;;;;;;70447:121;56247:190;;;;;;;;;;-1:-1:-1;56247:190:0;;;;;:::i;:::-;;:::i;75314:151::-;;;;;;;;;;-1:-1:-1;75314:151:0;;;;;:::i;:::-;;:::i;82372:315::-;;;;;;;;;;-1:-1:-1;82372:315:0;;;;;:::i;:::-;;:::i;76542:204::-;;;;;;;;;;-1:-1:-1;76542:204:0;;;;;:::i;:::-;;:::i;79043:215::-;;;;;;;;;;-1:-1:-1;79043:215:0;;;;;:::i;:::-;;:::i;54604:33::-;;;;;;;;;;;;;;;;54444:31;;;;;;;;;;;;;;;;77974:102;;;;;;;;;;-1:-1:-1;77974:102:0;;;;;:::i;:::-;;:::i;69706:195::-;;;;;;;;;;-1:-1:-1;69706:195:0;;;;;:::i;:::-;;:::i;68931:207::-;;;;;;;;;;-1:-1:-1;68931:207:0;;;;;:::i;:::-;;:::i;53689:42::-;;;;;;;;;;-1:-1:-1;53689:42:0;;;;-1:-1:-1;;;;;53689:42:0;;;67890:203;;;;;;;;;;-1:-1:-1;67890:203:0;;;;;:::i;:::-;;:::i;70705:183::-;;;;;;;;;;-1:-1:-1;70705:183:0;;;;;:::i;:::-;;:::i;69353:158::-;;;;;;;;;;-1:-1:-1;69353:158:0;;;;;:::i;:::-;;:::i;76054:123::-;;;;;;;;;;-1:-1:-1;76054:123:0;;;;;:::i;:::-;-1:-1:-1;;;;;76145:16:0;76118:7;76145:16;;;:9;:16;;;;;;;76054:123;54222:42;;;;;;;;;;;;;;;;79956:220;;;;;;;;;;-1:-1:-1;79956:220:0;;;;;:::i;:::-;;:::i;80282:463::-;;;;;;;;;;;;;:::i;58722:695::-;;;;;;;;;;-1:-1:-1;58722:695:0;;;;;:::i;:::-;;:::i;69909:106::-;;;;;;;;;;-1:-1:-1;69909:106:0;;;;;:::i;:::-;;:::i;74705:104::-;;;;;;:::i;:::-;;:::i;54556:41::-;;;;;;;;;;;;;;;70027:153;;;;;;;;;;-1:-1:-1;70027:153:0;;;;;:::i;:::-;;:::i;58510:104::-;;;;;;;;;;;;;:::i;71045:2794::-;;;;;;:::i;:::-;;:::i;77509:285::-;;;;;;;;;;-1:-1:-1;77509:285:0;;;;;:::i;:::-;;:::i;68345:132::-;;;;;;;;;;-1:-1:-1;68345:132:0;;;;;:::i;:::-;;:::i;54359:34::-;;;;;;;;;;;;;;;;56581:132;;;;;;;;;;-1:-1:-1;56581:132:0;;;;;:::i;:::-;56648:13;56681:24;;;:15;:24;;;;;;;56581:132;74202:80;;;;;;;;;;-1:-1:-1;74202:80:0;;;;;:::i;:::-;;:::i;75473:265::-;;;;;;;;;;-1:-1:-1;75473:265:0;;;;;:::i;:::-;;:::i;68675:139::-;;;;;;;;;;-1:-1:-1;68675:139:0;;;;;:::i;:::-;;:::i;78585:450::-;;;;;;;;;;-1:-1:-1;78585:450:0;;;;;:::i;:::-;;:::i;56445:128::-;;;;;;;;;;-1:-1:-1;56445:128:0;;;;;:::i;:::-;;:::i;69146:199::-;;;;;;;;;;-1:-1:-1;69146:199:0;;;;;:::i;:::-;;:::i;70191:248::-;;;;;;;;;;-1:-1:-1;70191:248:0;;;;;:::i;:::-;;:::i;68822:101::-;;;;;;;;;;-1:-1:-1;68822:101:0;;;;;:::i;:::-;;:::i;54865:74::-;;;;;;;;;;;;54897:42;54865:74;;54402:33;;;;;;;;;;;;;;;;77802:164;;;;;;;;;;-1:-1:-1;77802:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;77923:25:0;;;77899:4;77923:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;77802:164;79732:212;;;;;;;;;;-1:-1:-1;79732:212:0;;;;;:::i;:::-;;:::i;54778:22::-;;;;;;;;;;-1:-1:-1;54778:22:0;;;;-1:-1:-1;;;;;54778:22:0;;;54521:26;;;;;;;;;;;;;;;;70576:121;;;;;;;;;;-1:-1:-1;70576:121:0;;;;;:::i;:::-;-1:-1:-1;;;;;70662:27:0;70638:4;70662:27;;;:17;:27;;;;;;;;;70576:121;81927:435;82012:4;82029:28;82068;82107:29;82147:36;-1:-1:-1;;;;;;82201:23:0;;;;;:64;;-1:-1:-1;;;;;;;82242:23:0;;;;;;;82201:64;:105;;;-1:-1:-1;;;;;;;82282:24:0;;;;;;;82201:105;:153;;;-1:-1:-1;;;;;;;82323:31:0;;;;;;;82201:153;82194:160;81927:435;-1:-1:-1;;;;;;81927:435:0:o;58402:100::-;58456:13;58489:5;58482:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58402:100;:::o;77302:199::-;77378:7;78165:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78165:16:0;77398:46;;;;-1:-1:-1;;;77398:46:0;;7106:2:1;77398:46:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;77398:46:0;;;;;;;;;-1:-1:-1;77469:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;77469:24:0;;77302:199::o;76754:361::-;76835:13;76851:16;76859:7;76851;:16::i;:::-;76835:32;;76892:5;-1:-1:-1;;;;;76886:11:0;:2;-1:-1:-1;;;;;76886:11:0;;;76878:49;;;;-1:-1:-1;;;76878:49:0;;7452:2:1;76878:49:0;;;7434:21:1;7491:2;7471:18;;;7464:30;7530:27;7510:18;;;7503:55;7575:18;;76878:49:0;7250:349:1;76878:49:0;80256:10;-1:-1:-1;;;;;76948:21:0;;;;:62;;-1:-1:-1;76973:37:0;76990:5;80256:10;77802:164;:::i;76973:37::-;76940:128;;;;-1:-1:-1;;;76940:128:0;;7806:2:1;76940:128:0;;;7788:21:1;7845:2;7825:18;;;7818:30;7884:32;7864:18;;;7857:60;7934:18;;76940:128:0;7604:354:1;76940:128:0;77079:28;77088:5;77095:2;77099:7;77079:8;:28::i;:::-;76824:291;76754:361;;:::o;76359:175::-;76425:13;76459:16;;;:7;:16;;;;;;76494:10;76486:40;;;;-1:-1:-1;;;76486:40:0;;7106:2:1;76486:40:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;76486:40:0;6904:341:1;76486:40:0;76359:175;;;:::o;68584:83::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68646:5:::1;:13:::0;;-1:-1:-1;;;;;;68646:13:0::1;-1:-1:-1::0;;;;;68646:13:0;;;::::1;::::0;;;::::1;::::0;;68584:83::o;79266:229::-;79350:7;79370:23;79387:5;79370:16;:23::i;:::-;79404:27;79423:7;79404:18;:27::i;:::-;79479:7;79451:24;53869:6;79451:5;:24;:::i;:::-;79450:36;;;;:::i;:::-;79442:45;79266:229;-1:-1:-1;;;79266:229:0:o;75746:300::-;75847:13;;75888:41;80256:10;75907:12;75921:7;75888:18;:41::i;:::-;75846:83;;;;75948:17;75940:52;;;;-1:-1:-1;;;75940:52:0;;9010:2:1;75940:52:0;;;8992:21:1;9049:2;9029:18;;;9022:30;9088:24;9068:18;;;9061:52;9130:18;;75940:52:0;8808:346:1;75940:52:0;76003:35;76013:5;76020:4;76026:2;76030:7;76003:9;:35::i;:::-;75835:211;;75746:300;;;:::o;76185:166::-;76250:7;76270:13;76286:19;76297:7;76286:10;:19::i;:::-;76270:35;;76323:20;76337:5;76323:13;:20::i;79503:221::-;79570:7;79579;79599:13;79615:18;79627:5;79615:11;:18::i;:::-;79599:34;;79644:15;79662:20;79676:5;79662:13;:20::i;:::-;79701:5;;79644:38;;-1:-1:-1;79503:221:0;;-1:-1:-1;;;79503:221:0:o;74817:489::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;74887:15:::1;74905:13;74932:11;;74920:8;73977:156:::0;;;74006:15;73977:156;;;;20324:25:1;;;;74040:16:0;20365:18:1;;;20358:34;74075:14:0;20469:18:1;;;20462:43;74108:10:0;20521:18:1;;;;20514:43;;;;73977:156:0;;;;;;;;;;20296:19:1;;;;73977:156:0;;;73953:191;;;;;;73847:342;74920:8:::1;:24;;;;:::i;:::-;74919:30;::::0;74948:1:::1;74919:30;:::i;:::-;74905:45;;;;;;;:::i;:::-;;;74887:63;;74961:18;74990:281;75026:18;75036:7;75026:9;:18::i;:::-;75009:13;::::0;73977:156;;;74006:15;73977:156;;;;20324:25:1;;;;74040:16:0;20365:18:1;;;20358:34;74075:14:0;20469:18:1;;;20462:43;74108:10:0;20521:18:1;;;;20514:43;;;;73977:156:0;;;;;;;;;;20296:19:1;;;;73977:156:0;;;73953:191;;;;;74998:24:::1;;;;:::i;:::-;74997:47;74990:281;;;75073:13;75100:11;;75088:8;73977:156:::0;;;74006:15;73977:156;;;;20324:25:1;;;;74040:16:0;20365:18:1;;;20358:34;74075:14:0;20469:18:1;;;20462:43;74108:10:0;20521:18:1;;;;20514:43;;;;73977:156:0;;;;;;;;;;20296:19:1;;;;73977:156:0;;;73953:191;;;;;;73847:342;75088:8:::1;:24;;;;:::i;:::-;75087:30;::::0;75116:1:::1;75087:30;:::i;:::-;75073:45;;;;;;;:::i;:::-;;;75060:58;;75148:10;75137:7;:21;75133:127;;;75178:5;;75133:127;75234:10;75224:20;;74990:281;;;75281:17;75290:7;75281:8;:17::i;:::-;74876:430;;74817:489::o:0;68101:236::-;68181:7;68190;68210:21;68269:16;68247:18;;68235:9;:30;;;;:::i;:::-;68234:51;;;;:::i;:::-;68304:9;;-1:-1:-1;;;;;68304:9:0;;68210:75;;-1:-1:-1;68101:236:0;-1:-1:-1;;;;68101:236:0:o;69519:175::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69608:6:::1;69593:11;;:21;;:45;;;;;69628:10;;69618:6;:20;;69593:45;69585:71;;;::::0;-1:-1:-1;;;69585:71:0;;9981:2:1;69585:71:0::1;::::0;::::1;9963:21:1::0;10020:2;10000:18;;;9993:30;10059:15;10039:18;;;10032:43;10092:18;;69585:71:0::1;9779:337:1::0;69585:71:0::1;69667:10;:19:::0;69519:175::o;68485:91::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68551:7:::1;:17:::0;;-1:-1:-1;;;;;;68551:17:0::1;-1:-1:-1::0;;;;;68551:17:0;;;::::1;::::0;;;::::1;::::0;;68485:91::o;56247:190::-;56310:20;78165:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78165:16:0;56343:46;;;;-1:-1:-1;;;56343:46:0;;7106:2:1;56343:46:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;56343:46:0;6904:341:1;56343:46:0;-1:-1:-1;56407:22:0;;;;:13;:22;;;;;;;56247:190::o;75314:151::-;75418:39;75435:4;75441:2;75445:7;75418:39;;;;;;;;;;;;:16;:39::i;82372:315::-;57005:6;;-1:-1:-1;;;57005:6:0;;;;57004:7;56996:35;;;;-1:-1:-1;;;56996:35:0;;10323:2:1;56996:35:0;;;10305:21:1;10362:2;10342:18;;;10335:30;-1:-1:-1;;;10381:18:1;;;10374:45;10436:18;;56996:35:0;10121:339:1;56996:35:0;82432:13:::1;::::0;82473:41:::1;80256:10:::0;82492:12:::1;80184:90:::0;82473:41:::1;82431:83;;;;82533:17;82525:52;;;::::0;-1:-1:-1;;;82525:52:0;;9010:2:1;82525:52:0::1;::::0;::::1;8992:21:1::0;9049:2;9029:18;;;9022:30;9088:24;9068:18;;;9061:52;9130:18;;82525:52:0::1;8808:346:1::0;82525:52:0::1;82590:35;82610:5;82617:7;82590:19;:35::i;:::-;82643:36;::::0;82671:7;;82667:1:::1;::::0;-1:-1:-1;;;;;82643:36:0;::::1;::::0;::::1;::::0;82667:1;;82643:36:::1;82420:267;;82372:315:::0;:::o;76542:204::-;-1:-1:-1;;;;;70533:27:0;;76603:7;70533:27;;;:17;:27;;;;;;;;76631:21;76623:51;;;;-1:-1:-1;;;76623:51:0;;10667:2:1;76623:51:0;;;10649:21:1;10706:2;10686:18;;;10679:30;10745:19;10725:18;;;10718:47;10782:18;;76623:51:0;10465:341:1;76623:51:0;-1:-1:-1;;;;;;76701:14:0;76685:13;76701:14;;;:7;:14;;;;;;;76542:204::o;79043:215::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;78141:4;78165:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78165:16:0;79126:46:::1;;;::::0;-1:-1:-1;;;79126:46:0;;7106:2:1;79126:46:0::1;::::0;::::1;7088:21:1::0;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;79126:46:0::1;6904:341:1::0;79126:46:0::1;79202:48;79224:5;79231:18;79241:7;79231:9;:18::i;79202:48::-;79183:16;::::0;;;:7:::1;:16;::::0;;;;;:67;;;;-1:-1:-1;79043:215:0:o;77974:102::-;78028:4;78165:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78165:16:0;:30;;78052:16;78045:23;77974:102;-1:-1:-1;;77974:102:0:o;69706:195::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69800:8:::1;69783:13;;:25;;:57;;;;-1:-1:-1::0;54193:20:0::1;54212:1;53869:6;54193:20;:::i;:::-;69812:8;:28;;69783:57;69775:85;;;::::0;-1:-1:-1;;;69775:85:0;;11143:2:1;69775:85:0::1;::::0;::::1;11125:21:1::0;11182:2;11162:18;;;11155:30;11221:17;11201:18;;;11194:45;11256:18;;69775:85:0::1;10941:339:1::0;69775:85:0::1;69871:11;:22:::0;69706:195::o;68931:207::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69040:12:::1;;69027:10;:25;69005:87;;;::::0;-1:-1:-1;;;69005:87:0;;11487:2:1;69005:87:0::1;::::0;::::1;11469:21:1::0;11526:2;11506:18;;;11499:30;-1:-1:-1;;;11545:18:1;;;11538:42;11597:18;;69005:87:0::1;11285:336:1::0;69005:87:0::1;69103:14;:27:::0;68931:207::o;67890:203::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68000:16:::1;67978:18;:38;;67970:65;;;::::0;-1:-1:-1;;;67970:65:0;;11828:2:1;67970:65:0::1;::::0;::::1;11810:21:1::0;11867:2;11847:18;;;11840:30;11906:16;11886:18;;;11879:44;11940:18;;67970:65:0::1;11626:338:1::0;67970:65:0::1;68046:18;:39:::0;67890:203::o;70705:183::-;70769:13;70803:16;;;:7;:16;;;;;;-1:-1:-1;;;;;70803:16:0;70839:19;70831:49;;;;-1:-1:-1;;;70831:49:0;;7106:2:1;70831:49:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;70831:49:0;6904:341:1;69353:158:0;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69442:6:::1;69427:11;;:21;;69419:54;;;::::0;-1:-1:-1;;;69419:54:0;;12171:2:1;69419:54:0::1;::::0;::::1;12153:21:1::0;12210:2;12190:18;;;12183:30;12249:22;12229:18;;;12222:50;12289:18;;69419:54:0::1;11969:344:1::0;69419:54:0::1;69484:10;:19:::0;69353:158::o;79956:220::-;80015:15;80053:24;53869:6;80053:5;:24;:::i;:::-;80043:34;;80141:27;80160:7;80141:18;:27::i;80282:463::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;80352:21:::1;80392:14:::0;80384:23:::1;;;::::0;::::1;;80433:4;::::0;80422:7:::1;::::0;-1:-1:-1;;;;;80422:7:0;;::::1;80433:4:::0;::::1;80422:15;80418:320;;;80463:4;::::0;80453:38:::1;::::0;-1:-1:-1;;;;;80463:4:0::1;80469:21;80453:9;:38::i;:::-;80320:425;80282:463::o:0;80418:320::-:1;80534:7;::::0;80524:34:::1;::::0;-1:-1:-1;;;;;80534:7:0::1;80543:14;80556:1;80543:10:::0;:14:::1;:::i;:::-;80524:9;:34::i;:::-;80590:5;::::0;80580:32:::1;::::0;-1:-1:-1;;;;;80590:5:0::1;80597:14;80610:1;80597:10:::0;:14:::1;:::i;80580:32::-;80691:4;::::0;80681:38:::1;::::0;-1:-1:-1;;;;;80691:4:0::1;80697:21;80681:9;:38::i;58722:695::-:0;80256:10;58828:19;56882:31;;;:17;:31;;;;;;;;56874:62;;;;-1:-1:-1;;;56874:62:0;;12520:2:1;56874:62:0;;;12502:21:1;12559:2;12539:18;;;12532:30;12598:20;12578:18;;;12571:48;12636:18;;56874:62:0;12318:342:1;56874:62:0;57005:6:::1;::::0;-1:-1:-1;;;57005:6:0;::::1;;;57004:7;56996:35;;;::::0;-1:-1:-1;;;56996:35:0;;10323:2:1;56996:35:0::1;::::0;::::1;10305:21:1::0;10362:2;10342:18;;;10335:30;-1:-1:-1;;;10381:18:1;;;10374:45;10436:18;;56996:35:0::1;10121:339:1::0;56996:35:0::1;58868:13:::2;58884:20;58892:11;58884:7;:20::i;:::-;58868:36;;58932:20;58940:11;58932:7;:20::i;:::-;-1:-1:-1::0;;;;;58923:29:0::2;:5;-1:-1:-1::0;;;;;58923:29:0::2;;58915:57;;;::::0;-1:-1:-1;;;58915:57:0;;12867:2:1;58915:57:0::2;::::0;::::2;12849:21:1::0;12906:2;12886:18;;;12879:30;12945:17;12925:18;;;12918:45;12980:18;;58915:57:0::2;12665:339:1::0;58915:57:0::2;80256:10:::0;-1:-1:-1;;;;;58991:21:0;::::2;;58983:50;;;::::0;-1:-1:-1;;;58983:50:0;;13211:2:1;58983:50:0::2;::::0;::::2;13193:21:1::0;13250:2;13230:18;;;13223:30;13289:18;13269;;;13262:46;13325:18;;58983:50:0::2;13009:340:1::0;58983:50:0::2;-1:-1:-1::0;;;;;59120:16:0;::::2;;::::0;;;:9:::2;:16;::::0;;;;:21;;59140:1:::2;::::0;59120:16;:21:::2;::::0;59140:1;;59120:21:::2;:::i;:::-;::::0;;;-1:-1:-1;59168:34:0::2;::::0;-1:-1:-1;59177:11:0;59190;59168:8:::2;:34::i;:::-;59264:20;::::0;;;:7:::2;:20;::::0;;;;;59257:27;;-1:-1:-1;;;;;;59257:27:0::2;::::0;;59369:40;59154:48;;-1:-1:-1;59154:48:0;;-1:-1:-1;;;;;59369:40:0;::::2;::::0;::::2;::::0;59264:20;;59369:40:::2;58849:568;58722:695:::0;;;;:::o;69909:106::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69986:9:::1;:21:::0;;-1:-1:-1;;;;;;69986:21:0::1;-1:-1:-1::0;;;;;69986:21:0;;;::::1;::::0;;;::::1;::::0;;69909:106::o;74705:104::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;74784:17:::1;74793:7;74784:8;:17::i;70027:153::-:0;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;70115:18:::1;:57:::0;;-1:-1:-1;;;;;;70115:57:0::1;-1:-1:-1::0;;;;;70115:57:0;;;::::1;::::0;;;::::1;::::0;;70027:153::o;58510:104::-;58566:13;58599:7;58592:14;;;;;:::i;71045:2794::-;71152:14;;71133:15;:33;;:67;;;;;71188:12;;71170:15;:30;71133:67;71111:130;;;;-1:-1:-1;;;71111:130:0;;13556:2:1;71111:130:0;;;13538:21:1;13595:2;13575:18;;;13568:30;13634:15;13614:18;;;13607:43;13667:18;;71111:130:0;13354:337:1;71111:130:0;71274:10;;71260:11;;:24;71252:55;;;;-1:-1:-1;;;71252:55:0;;13898:2:1;71252:55:0;;;13880:21:1;13937:2;13917:18;;;13910:30;13976:20;13956:18;;;13949:48;14014:18;;71252:55:0;13696:342:1;71252:55:0;71469:9;71482:10;71469:23;71447:99;;;;-1:-1:-1;;;71447:99:0;;14245:2:1;71447:99:0;;;14227:21:1;14284:2;14264:18;;;14257:30;14323:28;14303:18;;;14296:56;14369:18;;71447:99:0;14043:350:1;71447:99:0;71585:10;71559:13;71575:21;;;:9;:21;;;;;;71712:11;;71752:8;;71794:13;;71885:4;;71575:26;;;;71712:11;;71752:8;;71794:13;;71840:14;;-1:-1:-1;;;;;71885:4:0;;;71871:18;71867:216;;;-1:-1:-1;71917:1:0;71867:216;;;72021:10;;72012:5;:19;;:32;;;;;72036:8;72035:9;72012:32;72008:75;;;72060:11;;;;:::i;:::-;;;;72008:75;72142:10;;72130:22;;:9;:22;:::i;:::-;72117:9;:35;;72095:101;;;;-1:-1:-1;;;72095:101:0;;14741:2:1;72095:101:0;;;14723:21:1;14780:2;14760:18;;;14753:30;14819:18;14799;;;14792:46;14855:18;;72095:101:0;14539:340:1;72095:101:0;72317:13;;72290:24;72367:33;72386:14;72317:13;72367:33;:::i;:::-;72341:59;;72452:11;;72433:15;:30;;72411:105;;;;-1:-1:-1;;;72411:105:0;;15086:2:1;72411:105:0;;;15068:21:1;15125:2;15105:18;;;15098:30;15164:27;15144:18;;;15137:55;15209:18;;72411:105:0;14884:349:1;72411:105:0;72527:13;:31;;;72651:192;;;;72702:10;70509:4;70533:27;;;:17;:27;;;;;;;;72687:26;72679:63;;;;-1:-1:-1;;;72679:63:0;;15440:2:1;72679:63:0;;;15422:21:1;15479:2;15459:18;;;15452:30;15518:26;15498:18;;;15491:54;15562:18;;72679:63:0;15238:348:1;72679:63:0;72757:53;72774:19;72782:10;72774:7;:19::i;:::-;72795:14;72757:16;:53::i;:::-;72825:7;;;;;;;71045:2794;:::o;72651:192::-;72901:13;72936:1;72929:3;72918:8;73977:156;;;74006:15;73977:156;;;;20324:25:1;;;;74040:16:0;20365:18:1;;;20358:34;74075:14:0;20469:18:1;;;20462:43;74108:10:0;20521:18:1;;;;20514:43;;;;73977:156:0;;;;;;;;;;20296:19:1;;;;73977:156:0;;;73953:191;;;;;;73847:342;72918:8;:14;;;;:::i;:::-;72917:20;:28;;72944:1;72917:28;;;72940:1;72917:28;72901:44;;;;72975;72997:5;73004:14;72975:21;:44::i;:::-;72958:14;;;;:7;:14;;;;;;;;:61;;;;73039:7;:14;;;;;:27;;-1:-1:-1;;;;;;73039:27:0;73056:10;73039:27;;;73113:11;:13;;;;;;:::i;:::-;;;;;;73158:14;73143:12;:29;73139:120;;;73203:14;73188:29;;73242:5;73232:15;;73139:120;73294:5;73271:13;73285:5;73271:20;;;;;;;:::i;:::-;;:28;73310:22;;;;:15;:22;;;;;:30;;;73353:52;;73310:22;73387:10;73335:5;73353:9;:52::i;:::-;73475:7;;;;:::i;:::-;;;;73556:5;73542:11;:19;;;;73666:7;73654:8;;:19;73651:173;;73690:8;:18;;;73723:13;:28;;;73771:41;;784:25:1;;;73690:18:0;;73771:41;;772:2:1;757:18;73771:41:0;;;;;;;73651:173;71100:2739;;;;;;;;71045:2794;:::o;77509:285::-;-1:-1:-1;;;;;77612:24:0;;80256:10;77612:24;;77604:54;;;;-1:-1:-1;;;77604:54:0;;15933:2:1;77604:54:0;;;15915:21:1;15972:2;15952:18;;;15945:30;16011:19;15991:18;;;15984:47;16048:18;;77604:54:0;15731:341:1;77604:54:0;80256:10;77669:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;77669:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;77669:53:0;;;;;;;;;;77738:48;;586:41:1;;;77669:42:0;;80256:10;77738:48;;559:18:1;77738:48:0;;;;;;;77509:285;;:::o;68345:132::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;-1:-1:-1;;;;;68433:27:0;;;::::1;;::::0;;;:17:::1;:27;::::0;;;;:36;;-1:-1:-1;;68433:36:0::1;::::0;::::1;;::::0;;;::::1;::::0;;68345:132::o;74202:80::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;74259:6:::1;:15:::0;;;::::1;;-1:-1:-1::0;;;74259:15:0::1;::::0;;;::::1;::::0;;;::::1;::::0;;74202:80::o;75473:265::-;75597:31;75610:4;75616:2;75620:7;75597:12;:31::i;:::-;75647:48;75670:4;75676:2;75680:7;75689:5;75647:22;:48::i;:::-;75639:91;;;;-1:-1:-1;;;75639:91:0;;16279:2:1;75639:91:0;;;16261:21:1;16318:2;16298:18;;;16291:30;16357:32;16337:18;;;16330:60;16407:18;;75639:91:0;16077:354:1;75639:91:0;75473:265;;;;:::o;68675:139::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68765:4:::1;68741:21;:28;68733:51;;;::::0;-1:-1:-1;;;68733:51:0;;16638:2:1;68733:51:0::1;::::0;::::1;16620:21:1::0;16677:2;16657:18;;;16650:30;16716:12;16696:18;;;16689:40;16746:18;;68733:51:0::1;16436:334:1::0;68733:51:0::1;68795:4;:11:::0;;-1:-1:-1;;;;;;68795:11:0::1;-1:-1:-1::0;;;;;68795:11:0;;;::::1;::::0;;;::::1;::::0;;68675:139::o;78585:450::-;78141:4;78165:16;;;:7;:16;;;;;;78658:13;;-1:-1:-1;;;;;78165:16:0;78684:46;;;;-1:-1:-1;;;78684:46:0;;7106:2:1;78684:46:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;78684:46:0;6904:341:1;78684:46:0;78758:18;;;78840:16;;;:7;:16;;;;;;;-1:-1:-1;;;;;78758:18:0;;;;:32;;78805:7;;78828:29;;:11;:29::i;:::-;78887:16;;;;:7;:16;;;;;;78873:31;;:13;:31::i;:::-;78942:8;;78934:17;;;;:7;:17;;;;;;78920:32;;:13;:32::i;:::-;78979:8;;78968:7;:19;79002:24;79018:7;79002:15;:24::i;:::-;78758:269;;-1:-1:-1;;;;;;78758:269:0;;;;;;;;;;17056:25:1;;;;17097:18;;;17090:34;;;;17140:18;;;17133:34;;;;17183:18;;;17176:34;17254:14;17247:22;17226:19;;;17219:51;17286:19;;;17279:35;17028:19;;78758:269:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;78758:269:0;;;;;;;;;;;;:::i;56445:128::-;56510:15;56545:13;56559:5;56545:20;;;;;;;:::i;:::-;;;;56445:128;-1:-1:-1;;56445:128:0:o;69146:199::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;69255:8:::1;69238:14;;:25;69216:87;;;::::0;-1:-1:-1;;;69216:87:0;;11487:2:1;69216:87:0::1;::::0;::::1;11469:21:1::0;11526:2;11506:18;;;11499:30;-1:-1:-1;;;11545:18:1;;;11538:42;11597:18;;69216:87:0::1;11285:336:1::0;69216:87:0::1;69314:12;:23:::0;69146:199::o;70191:248::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;70280:15;70277:106:::1;;70343:1;70320:19;70330:8;-1:-1:-1::0;;;;;76145:16:0;76118:7;76145:16;;;:9;:16;;;;;;;76054:123;70320:19:::1;:24;;70312:59;;;::::0;-1:-1:-1;;;70312:59:0;;18167:2:1;70312:59:0::1;::::0;::::1;18149:21:1::0;18206:2;18186:18;;;18179:30;18245:24;18225:18;;;18218:52;18287:18;;70312:59:0::1;17965:346:1::0;70312:59:0::1;-1:-1:-1::0;;;;;70395:27:0;;;::::1;;::::0;;;:17:::1;:27;::::0;;;;:36;;-1:-1:-1;;70395:36:0::1;::::0;::::1;;::::0;;;::::1;::::0;;70191:248::o;68822:101::-;56775:4;;-1:-1:-1;;;;;56775:4:0;80256:10;-1:-1:-1;;;;;56759:20:0;;56751:54;;;;-1:-1:-1;;;56751:54:0;;8165:2:1;56751:54:0;;;8147:21:1;8204:2;8184:18;;;8177:30;-1:-1:-1;;;;;;;;;;;8223:18:1;;;8216:51;8284:18;;56751:54:0;7963:345:1;56751:54:0;68892:10:::1;:23:::0;68822:101::o;79732:212::-;79789:13;79823:24;53869:6;79823:5;:24;:::i;:::-;79815:32;;79913:23;79930:5;79913:16;:23::i;77123:171::-;77213:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;77213:29:0;-1:-1:-1;;;;;77213:29:0;;;;;;;;;77258:28;;77213:24;;77258:28;;;;;;;77123:171;;;:::o;57059:156::-;57150:5;53980:1;57132:23;;:50;;;;;54031:1;57159:5;:23;;57132:50;57124:83;;;;-1:-1:-1;;;57124:83:0;;18518:2:1;57124:83:0;;;18500:21:1;18557:2;18537:18;;;18530:30;18596:22;18576:18;;;18569:50;18636:18;;57124:83:0;18316:344:1;57223:174:0;57320:7;54140:1;57300:27;;:57;;;;-1:-1:-1;54193:20:0;54212:1;53869:6;54193:20;:::i;:::-;57331:7;:26;57300:57;57292:97;;;;-1:-1:-1;;;57292:97:0;;18867:2:1;57292:97:0;;;18849:21:1;18906:2;18886:18;;;18879:30;18945:29;18925:18;;;18918:57;18992:18;;57292:97:0;18665:351:1;78211:363:0;78304:13;78362:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78362:16:0;;78399:19;78391:49;;;;-1:-1:-1;;;78391:49:0;;7106:2:1;78391:49:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;78391:49:0;6904:341:1;78391:49:0;78485:5;-1:-1:-1;;;;;78474:16:0;:7;-1:-1:-1;;;;;78474:16:0;;:55;;;-1:-1:-1;78494:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;78494:35:0;;;:24;;:35;78474:55;:91;;;-1:-1:-1;;;;;;77923:25:0;;;77899:4;77923:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;78533:32;78453:113;;78211:363;;;;;:::o;59425:6443::-;57005:6;;-1:-1:-1;;;57005:6:0;;;;57004:7;56996:35;;;;-1:-1:-1;;;56996:35:0;;10323:2:1;56996:35:0;;;10305:21:1;10362:2;10342:18;;;10335:30;-1:-1:-1;;;10381:18:1;;;10374:45;10436:18;;56996:35:0;10121:339:1;56996:35:0;59549:4:::1;-1:-1:-1::0;;;;;59540:13:0::1;:5;-1:-1:-1::0;;;;;59540:13:0::1;;59532:39;;;::::0;-1:-1:-1;;;59532:39:0;;19223:2:1;59532:39:0::1;::::0;::::1;19205:21:1::0;19262:2;19242:18;;;19235:30;19301:15;19281:18;;;19274:43;19334:18;;59532:39:0::1;19021:337:1::0;59532:39:0::1;-1:-1:-1::0;;;;;59590:16:0;::::1;59582:57;;;::::0;-1:-1:-1;;;59582:57:0;;19565:2:1;59582:57:0::1;::::0;::::1;19547:21:1::0;19604:2;19584:18;;;19577:30;19643;19623:18;;;19616:58;19691:18;;59582:57:0::1;19363:352:1::0;59582:57:0::1;-1:-1:-1::0;;;;;59659:21:0;::::1;;::::0;;;:17:::1;:21;::::0;;;;;::::1;;59658:22;59650:63;;;::::0;-1:-1:-1;;;59650:63:0;;19922:2:1;59650:63:0::1;::::0;::::1;19904:21:1::0;19961:2;19941:18;;;19934:30;20000;19980:18;;;19973:58;20048:18;;59650:63:0::1;19720:352:1::0;59650:63:0::1;-1:-1:-1::0;;;;;59812:11:0;::::1;54897:42;59812:11;59808:6053;;;59840:35;59860:5;59867:7;59840:19;:35::i;:::-;59897:30;::::0;59919:7;;54897:42:::1;::::0;-1:-1:-1;;;;;59897:30:0;::::1;::::0;::::1;::::0;;;::::1;59947:36;::::0;59975:7;;59971:1:::1;::::0;54897:42:::1;::::0;59947:36:::1;::::0;59971:1;;59947:36:::1;59808:6053;;;60111:36;60120:5;60135:1;60139:7;60111:8;:36::i;:::-;60334:7;60330:2;-1:-1:-1::0;;;;;60315:27:0::1;60324:4;-1:-1:-1::0;;;;;60315:27:0::1;;;;;;;;;;;60371:2;-1:-1:-1::0;;;;;60363:10:0::1;:4;-1:-1:-1::0;;;;;60363:10:0::1;;60359:254;;;60591:7;;60359:254;-1:-1:-1::0;;;;;70533:27:0;;;61346:22:::1;70533:27:::0;;;:17;:27;;;;;;;;;;;;;;;;;;;;;61671:609;::::1;;;-1:-1:-1::0;;;;;61856:15:0;::::1;;::::0;;;:9:::1;:15;::::0;;;;:20;;61875:1:::1;::::0;61856:15;:20:::1;::::0;61875:1;;61856:20:::1;:::i;:::-;::::0;;;-1:-1:-1;61671:609:0::1;::::0;-1:-1:-1;61671:609:0::1;;-1:-1:-1::0;;;;;62249:15:0;::::1;;::::0;;;:9:::1;:15;::::0;;;;62242:22;61671:609:::1;62440:15;62436:845;;;-1:-1:-1::0;;;;;62619:13:0;::::1;;::::0;;;:9:::1;:13;::::0;;;;:18;;62636:1:::1;::::0;62619:13;:18:::1;::::0;62636:1;;62619:18:::1;:::i;:::-;::::0;;;-1:-1:-1;62436:845:0::1;::::0;-1:-1:-1;62436:845:0::1;;-1:-1:-1::0;;;;;62663:11:0;::::1;;::::0;;;:7:::1;:11;::::0;;;;;62659:622:::1;;-1:-1:-1::0;;;;;62949:13:0;::::1;;::::0;;;:9:::1;:13;::::0;;;;62965:1:::1;62949:17:::0;;62659:622:::1;63328:15;63324:2272;;;63719:16;::::0;;;:7:::1;:16;::::0;;;;:21;;-1:-1:-1;;;;;;63719:21:0::1;-1:-1:-1::0;;;;;63719:21:0;::::1;;::::0;;63324:2272:::1;;;-1:-1:-1::0;;;;;63884:11:0;::::1;63859:22;63884:11:::0;;;:7:::1;:11;::::0;;;;;63920:19;63916:1665:::1;;64061:16;::::0;;;:7:::1;:16;::::0;;;;;;;:21;;-1:-1:-1;;;;;;64061:21:0::1;-1:-1:-1::0;;;;;64061:21:0;::::1;::::0;;::::1;::::0;;;64191:11;;:7:::1;:11:::0;;;;;:21;;;63916:1665:::1;;;64283:7:::0;64261:19:::1;64409:37;64418:14:::0;64283:7;64409:8:::1;:37::i;:::-;64653;::::0;64387:59;;-1:-1:-1;64387:59:0;;64674:1:::1;::::0;-1:-1:-1;;;;;64653:37:0;::::1;::::0;::::1;::::0;64674:1;;64653:37:::1;64793:14:::0;64834:29;;::::1;64830:112;;;-1:-1:-1::0;64907:11:0;64830:112:::1;65078:20;::::0;;;:7:::1;:20;::::0;;;;65071:27;;-1:-1:-1;;;;;;65071:27:0::1;::::0;;65198:30;;::::1;65194:368;;65365:21;::::0;;;:7:::1;:21;::::0;;;;;;;:26;;-1:-1:-1;;;;;;65365:26:0::1;-1:-1:-1::0;;;;;65365:26:0;::::1;::::0;;::::1;::::0;;;65512:11;;:7:::1;:11:::0;;;;;:26;;;65194:368:::1;64238:1343;;;63916:1665;63762:1834;63324:2272;65776:17;65771:79;;-1:-1:-1::0;;;;;65821:13:0;::::1;;::::0;;;:7:::1;:13;::::0;;;;65814:20;65771:79:::1;60001:5860;;59425:6443:::0;;;;:::o;74290:407::-;74344:13;74360:16;;;:7;:16;;;;;;-1:-1:-1;;;;;74360:16:0;74395:19;74387:49;;;;-1:-1:-1;;;74387:49:0;;7106:2:1;74387:49:0;;;7088:21:1;7145:2;7125:18;;;7118:30;-1:-1:-1;;;7164:18:1;;;7157:47;7221:18;;74387:49:0;6904:341:1;74387:49:0;74447:35;74467:5;74474:7;74447:19;:35::i;:::-;74497:9;:13;74493:145;;74527:12;74544:5;-1:-1:-1;;;;;74544:10:0;74562:9;74544:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74526:50;;;74599:7;74591:35;;;;-1:-1:-1;;;74591:35:0;;20980:2:1;74591:35:0;;;20962:21:1;21019:2;20999:18;;;20992:30;21058:17;21038:18;;;21031:45;21093:18;;74591:35:0;20778:339:1;74591:35:0;74511:127;74493:145;74653:36;;74681:7;;74677:1;;-1:-1:-1;;;;;74653:36:0;;;;;74677:1;;74653:36;74333:364;74290:407;:::o;82695:635::-;82776:36;82785:5;82800:1;82804:7;82776:8;:36::i;:::-;82856:16;;;;:7;:16;;;;;;82842:31;;:13;:31::i;:::-;82825:13;;:48;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;82893:14:0;;;;;;:7;:14;;;;;;;;82886:21;;;82925:16;;;:7;:16;;;;;82918:23;;-1:-1:-1;;;;;;82918:23:0;;;82959:7;:16;;;;;82952:23;;;83013:15;:24;;;;;;83084:11;;83013:24;;82893:14;83070:13;;:26;;;;;;;:::i;:::-;;;83048:48;;83139:11;83107:13;83121:14;83107:29;;;;;;;:::i;:::-;;:43;83161:28;;;;:15;:28;;;;;:45;;;83217:11;:13;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;83247:16:0;;;;;;:9;:16;;;;;:21;;83267:1;;83247:16;:21;;83267:1;;83247:21;:::i;:::-;;;;-1:-1:-1;;83294:28:0;;83317:1;784:25:1;;;83317:1:0;83308:7;;83294:28;;772:2:1;757:18;83294:28:0;;;;;;;;82765:565;;82695:635;;:::o;80753:166::-;80821:12;80838:5;-1:-1:-1;;;;;80838:10:0;80856:4;80838:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80820:45;;;80884:7;80876:35;;;;-1:-1:-1;;;80876:35:0;;20980:2:1;80876:35:0;;;20962:21:1;21019:2;20999:18;;;20992:30;21058:17;21038:18;;;21031:45;21093:18;;80876:35:0;20778:339:1;66370:1512:0;66448:19;66503:11;66488;:26;;66480:56;;;;-1:-1:-1;;;66480:56:0;;21514:2:1;66480:56:0;;;21496:21:1;21553:2;21533:18;;;21526:30;21592:19;21572:18;;;21565:47;21629:18;;66480:56:0;21312:341:1;66480:56:0;66549:19;66585:20;;;:7;:20;;;;;;66571:35;;:13;:35::i;:::-;66617:19;66653:20;;;:7;:20;;;;;;66549:57;;-1:-1:-1;66617:19:0;66639:35;;:13;:35::i;:::-;66617:57;-1:-1:-1;66718:11:0;66617:57;66810:11;66855;66883:26;;;66879:212;;-1:-1:-1;66943:11:0;;-1:-1:-1;66984:11:0;;-1:-1:-1;67027:11:0;;-1:-1:-1;67068:11:0;66879:212;67103:21;;;;:7;:21;;;;;:37;;67128:12;;67103:21;:37;;67128:12;;67103:37;:::i;:::-;;;;-1:-1:-1;67153:23:0;;-1:-1:-1;67179:27:0;67194:12;67179;:27;:::i;:::-;67153:53;;67240:13;;67222:15;:31;67219:197;;;67270:8;:23;;;67308:13;:31;;;67359:45;;784:25:1;;;67270:23:0;;67359:45;;772:2:1;757:18;67359:45:0;;;;;;;67219:197;67436:27;;;;:13;:27;;;;;:29;;;;;;:::i;:::-;;;;-1:-1:-1;;67485:21:0;;;;:7;:21;;;;;;;;67478:28;;;67544:15;:29;;;;;;67620:11;;67544:29;;67485:21;67606:13;;:26;;;;;;;:::i;:::-;;;67584:48;;67675:11;67643:13;67657:14;67643:29;;;;;;;:::i;:::-;;:43;67697:28;;;;:15;:28;;;;;:45;;;67753:11;:13;;;;;;:::i;:::-;;;;;;67812:12;67798;67784:58;67826:15;67784:58;;;;784:25:1;;772:2;757:18;;638:177;67784:58:0;;;;;;;;-1:-1:-1;67862:12:0;;66370:1512;-1:-1:-1;;;;;;;;;;66370:1512:0:o;65876:486::-;65956:22;65995:16;;;:7;:16;;;;;;65981:31;;:13;:31::i;:::-;65956:56;;66043:8;66023:7;:16;66031:7;66023:16;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;66064:18:0;;-1:-1:-1;66085:25:0;66102:8;66085:14;:25;:::i;:::-;66064:46;;66139:13;;66126:10;:26;66123:177;;;66169:8;:18;;;66202:13;:26;;;66248:40;;784:25:1;;;66169:18:0;;66248:40;;772:2:1;757:18;66248:40:0;;;;;;;66123:177;66334:7;66331:1;66317:37;66343:10;66317:37;;;;784:25:1;;772:2;757:18;;638:177;80932:744:0;81044:4;81864:20;;81903:8;81061:586;;81100:72;;-1:-1:-1;;;81100:72:0;;-1:-1:-1;;;;;81100:36:0;;;;;:72;;80256:10;;81151:4;;81157:7;;81166:5;;81100:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81100:72:0;;;;;;;;-1:-1:-1;;81100:72:0;;;;;;;;;;;;:::i;:::-;;;81096:540;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81346:13:0;;81342:107;;81389:40;;-1:-1:-1;;;81389:40:0;;16279:2:1;81389:40:0;;;16261:21:1;16318:2;16298:18;;;16291:30;16357:32;16337:18;;;16330:60;16407:18;;81389:40:0;16077:354:1;81342:107:0;81594:6;81588:13;81579:6;81575:2;81571:15;81564:38;81096:540;-1:-1:-1;;;;;;81223:55:0;-1:-1:-1;;;81223:55:0;;-1:-1:-1;81216:62:0;;81096:540;-1:-1:-1;81664:4:0;80932:744;;;;;;;:::o;14:177:1:-;-1:-1:-1;;;;;;92:5:1;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;1051:258::-;1123:1;1133:113;1147:6;1144:1;1141:13;1133:113;;;1223:11;;;1217:18;1204:11;;;1197:39;1169:2;1162:10;1133:113;;;1264:6;1261:1;1258:13;1255:48;;;-1:-1:-1;;1299:1:1;1281:16;;1274:27;1051:258::o;1314:::-;1356:3;1394:5;1388:12;1421:6;1416:3;1409:19;1437:63;1493:6;1486:4;1481:3;1477:14;1470:4;1463:5;1459:16;1437:63;:::i;:::-;1554:2;1533:15;-1:-1:-1;;1529:29:1;1520:39;;;;1561:4;1516:50;;1314:258;-1:-1:-1;;1314:258:1:o;1577:220::-;1726:2;1715:9;1708:21;1689:4;1746:45;1787:2;1776:9;1772:18;1764:6;1746:45;:::i;1802:180::-;1861:6;1914:2;1902:9;1893:7;1889:23;1885:32;1882:52;;;1930:1;1927;1920:12;1882:52;-1:-1:-1;1953:23:1;;1802:180;-1:-1:-1;1802:180:1:o;1987:196::-;2055:20;;-1:-1:-1;;;;;2104:54:1;;2094:65;;2084:93;;2173:1;2170;2163:12;2188:254;2256:6;2264;2317:2;2305:9;2296:7;2292:23;2288:32;2285:52;;;2333:1;2330;2323:12;2285:52;2356:29;2375:9;2356:29;:::i;:::-;2346:39;2432:2;2417:18;;;;2404:32;;-1:-1:-1;;;2188:254:1:o;2447:186::-;2506:6;2559:2;2547:9;2538:7;2534:23;2530:32;2527:52;;;2575:1;2572;2565:12;2527:52;2598:29;2617:9;2598:29;:::i;2638:248::-;2706:6;2714;2767:2;2755:9;2746:7;2742:23;2738:32;2735:52;;;2783:1;2780;2773:12;2735:52;-1:-1:-1;;2806:23:1;;;2876:2;2861:18;;;2848:32;;-1:-1:-1;2638:248:1:o;2891:328::-;2968:6;2976;2984;3037:2;3025:9;3016:7;3012:23;3008:32;3005:52;;;3053:1;3050;3043:12;3005:52;3076:29;3095:9;3076:29;:::i;:::-;3066:39;;3124:38;3158:2;3147:9;3143:18;3124:38;:::i;:::-;3114:48;;3209:2;3198:9;3194:18;3181:32;3171:42;;2891:328;;;;;:::o;4035:160::-;4100:20;;4156:13;;4149:21;4139:32;;4129:60;;4185:1;4182;4175:12;4200:254;4265:6;4273;4326:2;4314:9;4305:7;4301:23;4297:32;4294:52;;;4342:1;4339;4332:12;4294:52;4365:29;4384:9;4365:29;:::i;:::-;4355:39;;4413:35;4444:2;4433:9;4429:18;4413:35;:::i;4459:180::-;4515:6;4568:2;4556:9;4547:7;4543:23;4539:32;4536:52;;;4584:1;4581;4574:12;4536:52;4607:26;4623:9;4607:26;:::i;4644:184::-;-1:-1:-1;;;4693:1:1;4686:88;4793:4;4790:1;4783:15;4817:4;4814:1;4807:15;4833:275;4904:2;4898:9;4969:2;4950:13;;-1:-1:-1;;4946:27:1;4934:40;;5004:18;4989:34;;5025:22;;;4986:62;4983:88;;;5051:18;;:::i;:::-;5087:2;5080:22;4833:275;;-1:-1:-1;4833:275:1:o;5113:186::-;5161:4;5194:18;5186:6;5183:30;5180:56;;;5216:18;;:::i;:::-;-1:-1:-1;5282:2:1;5261:15;-1:-1:-1;;5257:29:1;5288:4;5253:40;;5113:186::o;5304:888::-;5399:6;5407;5415;5423;5476:3;5464:9;5455:7;5451:23;5447:33;5444:53;;;5493:1;5490;5483:12;5444:53;5516:29;5535:9;5516:29;:::i;:::-;5506:39;;5564:38;5598:2;5587:9;5583:18;5564:38;:::i;:::-;5554:48;;5649:2;5638:9;5634:18;5621:32;5611:42;;5704:2;5693:9;5689:18;5676:32;5731:18;5723:6;5720:30;5717:50;;;5763:1;5760;5753:12;5717:50;5786:22;;5839:4;5831:13;;5827:27;-1:-1:-1;5817:55:1;;5868:1;5865;5858:12;5817:55;5904:2;5891:16;5929:48;5945:31;5973:2;5945:31;:::i;:::-;5929:48;:::i;:::-;6000:2;5993:5;5986:17;6040:7;6035:2;6030;6026;6022:11;6018:20;6015:33;6012:53;;;6061:1;6058;6051:12;6012:53;6116:2;6111;6107;6103:11;6098:2;6091:5;6087:14;6074:45;6160:1;6155:2;6150;6143:5;6139:14;6135:23;6128:34;6181:5;6171:15;;;;;5304:888;;;;;;;:::o;6197:260::-;6265:6;6273;6326:2;6314:9;6305:7;6301:23;6297:32;6294:52;;;6342:1;6339;6332:12;6294:52;6365:29;6384:9;6365:29;:::i;:::-;6355:39;;6413:38;6447:2;6436:9;6432:18;6413:38;:::i;6462:437::-;6541:1;6537:12;;;;6584;;;6605:61;;6659:4;6651:6;6647:17;6637:27;;6605:61;6712:2;6704:6;6701:14;6681:18;6678:38;6675:218;;;-1:-1:-1;;;6746:1:1;6739:88;6850:4;6847:1;6840:15;6878:4;6875:1;6868:15;6675:218;;6462:437;;;:::o;8313:184::-;-1:-1:-1;;;8362:1:1;8355:88;8462:4;8459:1;8452:15;8486:4;8483:1;8476:15;8502:168;8542:7;8608:1;8604;8600:6;8596:14;8593:1;8590:21;8585:1;8578:9;8571:17;8567:45;8564:71;;;8615:18;;:::i;:::-;-1:-1:-1;8655:9:1;;8502:168::o;8675:128::-;8715:3;8746:1;8742:6;8739:1;8736:13;8733:39;;;8752:18;;:::i;:::-;-1:-1:-1;8788:9:1;;8675:128::o;9159:184::-;-1:-1:-1;;;9208:1:1;9201:88;9308:4;9305:1;9298:15;9332:4;9329:1;9322:15;9348:112;9380:1;9406;9396:35;;9411:18;;:::i;:::-;-1:-1:-1;9445:9:1;;9348:112::o;9465:184::-;-1:-1:-1;;;9514:1:1;9507:88;9614:4;9611:1;9604:15;9638:4;9635:1;9628:15;9654:120;9694:1;9720;9710:35;;9725:18;;:::i;:::-;-1:-1:-1;9759:9:1;;9654:120::o;10811:125::-;10851:4;10879:1;10876;10873:8;10870:34;;;10884:18;;:::i;:::-;-1:-1:-1;10921:9:1;;10811:125::o;14398:136::-;14437:3;14465:5;14455:39;;14474:18;;:::i;:::-;-1:-1:-1;;;14510:18:1;;14398:136::o;15591:135::-;15630:3;-1:-1:-1;;15651:17:1;;15648:43;;;15671:18;;:::i;:::-;-1:-1:-1;15718:1:1;15707:13;;15591:135::o;17325:635::-;17405:6;17458:2;17446:9;17437:7;17433:23;17429:32;17426:52;;;17474:1;17471;17464:12;17426:52;17507:9;17501:16;17540:18;17532:6;17529:30;17526:50;;;17572:1;17569;17562:12;17526:50;17595:22;;17648:4;17640:13;;17636:27;-1:-1:-1;17626:55:1;;17677:1;17674;17667:12;17626:55;17706:2;17700:9;17731:48;17747:31;17775:2;17747:31;:::i;17731:48::-;17802:2;17795:5;17788:17;17842:7;17837:2;17832;17828;17824:11;17820:20;17817:33;17814:53;;;17863:1;17860;17853:12;17814:53;17876:54;17927:2;17922;17915:5;17911:14;17906:2;17902;17898:11;17876:54;:::i;:::-;17949:5;17325:635;-1:-1:-1;;;;;17325:635:1:o;21658:512::-;21852:4;-1:-1:-1;;;;;21962:2:1;21954:6;21950:15;21939:9;21932:34;22014:2;22006:6;22002:15;21997:2;21986:9;21982:18;21975:43;;22054:6;22049:2;22038:9;22034:18;22027:34;22097:3;22092:2;22081:9;22077:18;22070:31;22118:46;22159:3;22148:9;22144:19;22136:6;22118:46;:::i;22175:249::-;22244:6;22297:2;22285:9;22276:7;22272:23;22268:32;22265:52;;;22313:1;22310;22303:12;22265:52;22345:9;22339:16;22364:30;22388:5;22364:30;:::i

Swarm Source

ipfs://1e111a1df4a28d4f1931a31bf43916d3927fcd4089eb14d334200a080914f628
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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