ETH Price: $3,583.42 (-3.01%)

Token

Scrambles (SCRM)
 

Overview

Max Total Supply

963 SCRM

Holders

289

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
g3rmv.eth
Balance
5 SCRM
0x9D3bea10A103635776ce77377C3079613B3238DB
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

963 scrambles All Free, All On-Chain, All Truly Random .

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Scrambles

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// File: Base64.sol


pragma solidity ^0.8.2;

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

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

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

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

    bytes memory table = TABLE;

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

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

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

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

        mstore(resultPtr, out)

        resultPtr := add(resultPtr, 4)
      }

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

      mstore(result, encodedLen)
    }

    return string(result);
  }
}

// File: SVG721.sol


// attributes added by fatlion
pragma solidity ^0.8.0;


library SVG721 {
  function metadata(
    string memory tokenName,
    string memory tokenDescription,
    string memory svgString,
    string memory attributes
  ) internal pure returns (string memory) {
    string memory json = string(abi.encodePacked('{"name":"', tokenName, '","description":"', tokenDescription, '","image": "data:image/svg+xml;base64,', Base64.encode(bytes(svgString)),'",',attributes,'}'));
    return string(abi.encodePacked("data:application/json;base64,", Base64.encode(bytes(json))));
  }
}

// File: @chainlink/contracts/src/v0.8/VRFRequestIDBase.sol


pragma solidity ^0.8.0;

contract VRFRequestIDBase {

  /**
   * @notice returns the seed which is actually input to the VRF coordinator
   *
   * @dev To prevent repetition of VRF output due to repetition of the
   * @dev user-supplied seed, that seed is combined in a hash with the
   * @dev user-specific nonce, and the address of the consuming contract. The
   * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in
   * @dev the final seed, but the nonce does protect against repetition in
   * @dev requests which are included in a single block.
   *
   * @param _userSeed VRF seed input provided by user
   * @param _requester Address of the requesting contract
   * @param _nonce User-specific nonce at the time of the request
   */
  function makeVRFInputSeed(
    bytes32 _keyHash,
    uint256 _userSeed,
    address _requester,
    uint256 _nonce
  )
    internal
    pure
    returns (
      uint256
    )
  {
    return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));
  }

  /**
   * @notice Returns the id for this request
   * @param _keyHash The serviceAgreement ID to be used for this request
   * @param _vRFInputSeed The seed to be passed directly to the VRF
   * @return The id for this request
   *
   * @dev Note that _vRFInputSeed is not the seed passed by the consuming
   * @dev contract, but the one generated by makeVRFInputSeed
   */
  function makeRequestId(
    bytes32 _keyHash,
    uint256 _vRFInputSeed
  )
    internal
    pure
    returns (
      bytes32
    )
  {
    return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));
  }
}
// File: @chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol


pragma solidity ^0.8.0;

interface LinkTokenInterface {

  function allowance(
    address owner,
    address spender
  )
    external
    view
    returns (
      uint256 remaining
    );

  function approve(
    address spender,
    uint256 value
  )
    external
    returns (
      bool success
    );

  function balanceOf(
    address owner
  )
    external
    view
    returns (
      uint256 balance
    );

  function decimals()
    external
    view
    returns (
      uint8 decimalPlaces
    );

  function decreaseApproval(
    address spender,
    uint256 addedValue
  )
    external
    returns (
      bool success
    );

  function increaseApproval(
    address spender,
    uint256 subtractedValue
  ) external;

  function name()
    external
    view
    returns (
      string memory tokenName
    );

  function symbol()
    external
    view
    returns (
      string memory tokenSymbol
    );

  function totalSupply()
    external
    view
    returns (
      uint256 totalTokensIssued
    );

  function transfer(
    address to,
    uint256 value
  )
    external
    returns (
      bool success
    );

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  )
    external
    returns (
      bool success
    );

  function transferFrom(
    address from,
    address to,
    uint256 value
  )
    external
    returns (
      bool success
    );

}

// File: @chainlink/contracts/src/v0.8/VRFConsumerBase.sol


pragma solidity ^0.8.0;



/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constuctor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash), and have told you the minimum LINK
 * @dev price for VRF service. Make sure your contract has sufficient LINK, and
 * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you
 * @dev want to generate randomness from.
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomness method.
 *
 * @dev The randomness argument to fulfillRandomness is the actual random value
 * @dev generated from your seed.
 *
 * @dev The requestId argument is generated from the keyHash and the seed by
 * @dev makeRequestId(keyHash, seed). If your contract could have concurrent
 * @dev requests open, you can use the requestId to track which seed is
 * @dev associated with which randomness. See VRFRequestIDBase.sol for more
 * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.)
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ. (Which is critical to making unpredictable randomness! See the
 * @dev next section.)
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the ultimate input to the VRF is mixed with the block hash of the
 * @dev block in which the request is made, user-provided seeds have no impact
 * @dev on its economic security properties. They are only included for API
 * @dev compatability with previous versions of this contract.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request.
 */
abstract contract VRFConsumerBase is VRFRequestIDBase {

  /**
   * @notice fulfillRandomness handles the VRF response. Your contract must
   * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
   * @notice principles to keep in mind when implementing your fulfillRandomness
   * @notice method.
   *
   * @dev VRFConsumerBase expects its subcontracts to have a method with this
   * @dev signature, and will call it once it has verified the proof
   * @dev associated with the randomness. (It is triggered via a call to
   * @dev rawFulfillRandomness, below.)
   *
   * @param requestId The Id initially returned by requestRandomness
   * @param randomness the VRF output
   */
  function fulfillRandomness(
    bytes32 requestId,
    uint256 randomness
  )
    internal
    virtual;

  /**
   * @dev In order to keep backwards compatibility we have kept the user
   * seed field around. We remove the use of it because given that the blockhash
   * enters later, it overrides whatever randomness the used seed provides.
   * Given that it adds no security, and can easily lead to misunderstandings,
   * we have removed it from usage and can now provide a simpler API.
   */
  uint256 constant private USER_SEED_PLACEHOLDER = 0;

  /**
   * @notice requestRandomness initiates a request for VRF output given _seed
   *
   * @dev The fulfillRandomness method receives the output, once it's provided
   * @dev by the Oracle, and verified by the vrfCoordinator.
   *
   * @dev The _keyHash must already be registered with the VRFCoordinator, and
   * @dev the _fee must exceed the fee specified during registration of the
   * @dev _keyHash.
   *
   * @dev The _seed parameter is vestigial, and is kept only for API
   * @dev compatibility with older versions. It can't *hurt* to mix in some of
   * @dev your own randomness, here, but it's not necessary because the VRF
   * @dev oracle will mix the hash of the block containing your request into the
   * @dev VRF seed it ultimately uses.
   *
   * @param _keyHash ID of public key against which randomness is generated
   * @param _fee The amount of LINK to send with the request
   *
   * @return requestId unique ID for this request
   *
   * @dev The returned requestId can be used to distinguish responses to
   * @dev concurrent requests. It is passed as the first argument to
   * @dev fulfillRandomness.
   */
  function requestRandomness(
    bytes32 _keyHash,
    uint256 _fee
  )
    internal
    returns (
      bytes32 requestId
    )
  {
    LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));
    // This is the seed passed to VRFCoordinator. The oracle will mix this with
    // the hash of the block containing this request to obtain the seed/input
    // which is finally passed to the VRF cryptographic machinery.
    uint256 vRFSeed  = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]);
    // nonces[_keyHash] must stay in sync with
    // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above
    // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).
    // This provides protection against the user repeating their input seed,
    // which would result in a predictable/duplicate output, if multiple such
    // requests appeared in the same block.
    nonces[_keyHash] = nonces[_keyHash] + 1;
    return makeRequestId(_keyHash, vRFSeed);
  }

  LinkTokenInterface immutable internal LINK;
  address immutable private vrfCoordinator;

  // Nonces for each VRF key from which randomness has been requested.
  //
  // Must stay in sync with VRFCoordinator[_keyHash][this]
  mapping(bytes32 /* keyHash */ => uint256 /* nonce */) private nonces;

  /**
   * @param _vrfCoordinator address of VRFCoordinator contract
   * @param _link address of LINK token contract
   *
   * @dev https://docs.chain.link/docs/link-token-contracts
   */
  constructor(
    address _vrfCoordinator,
    address _link
  ) {
    vrfCoordinator = _vrfCoordinator;
    LINK = LinkTokenInterface(_link);
  }

  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
  // the origin of the call
  function rawFulfillRandomness(
    bytes32 requestId,
    uint256 randomness
  )
    external
  {
    require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill");
    fulfillRandomness(requestId, randomness);
  }
}

// File: @openzeppelin/contracts/utils/math/SafeMath.sol


// OpenZeppelin Contracts v4.4.0 (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


// OpenZeppelin Contracts v4.4.0 (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }
        return computedHash;
    }
}

// File: @openzeppelin/contracts/utils/Counters.sol


// OpenZeppelin Contracts v4.4.0 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.0 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts v4.4.0 (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.4.0 (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


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

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

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

// File: IScrambles.sol


pragma solidity ^0.8.4;


interface IScrambles is IERC721Enumerable {
    function mint(uint8 windowIndex, uint8 amount, bytes32[] calldata merkleProof) external;
    function unpause() external;
    function pause() external;
    function editRedemptionWindow(uint8 _windowID, bytes32 _merkleRoot, bool _open, uint8 _maxPerWallet) external;
    function getCoreNumbers(uint256 tokenId) external returns(string memory);
}
// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


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

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

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

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts v4.4.0 (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

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

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol


// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol


// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Burnable.sol)

pragma solidity ^0.8.0;



/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol


// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Pausable.sol)

pragma solidity ^0.8.0;



/**
 * @dev ERC721 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC721Pausable is ERC721, Pausable {
    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        require(!paused(), "ERC721Pausable: token transfer while paused");
    }
}

// File: Scrambles.sol



pragma solidity ^0.8.4;













/*
* @title ERC721 token for Scrambles
*
* @author original logic by Niftydude, extended by @bitcoinski, extended again by @georgefatlion
*/
                                                                                                                                               
contract Scrambles is IScrambles, ERC721Enumerable, ERC721Pausable, ERC721Burnable, Ownable, VRFConsumerBase {
    using Strings for uint256;
    using Strings for uint8;
    using SafeMath for uint256;
    using Counters for Counters.Counter;

    Counters.Counter private generalCounter; 
    uint public constant MAX_MINT = 963;

    // VRF stuff
    address public VRFCoordinator;
    address public LinkToken;
    bytes32 internal keyHash;
    uint256 public baseSeed;
  
    struct RedemptionWindow {
        bool open;
        uint8 maxRedeemPerWallet;
        bytes32 merkleRoot;
    }

    mapping(uint8 => RedemptionWindow) public redemptionWindows;
    mapping(address => uint8) public mintedTotal;
    mapping(uint8 => string[]) colours;

    // links
    string public _contractURI;

    bool public revealed;

    event Minted(address indexed account, string tokens);

    /**
    * @notice Constructor to create Scrambles contract
    * 
    * @param _name the token name
    * @param _symbol the token symbol
    * @param _maxRedeemPerWallet the max mint per redemption by index
    * @param _merkleRoots the merkle root for redemption window by index
    * @param _contractMetaDataURI the respective contract meta data URI
    * @param _VRFCoordinator the address of the vrf coordinator
    * @param _LinkToken link token
    * @param _keyHash chainlink keyhash
    */
    
    constructor (
        string memory _name, 
        string memory _symbol,
        uint8[] memory _maxRedeemPerWallet,
        bytes32[] memory _merkleRoots,
        string memory _contractMetaDataURI,
        address _VRFCoordinator, 
        address _LinkToken,
        bytes32 _keyHash
    ) 
    
    VRFConsumerBase(_VRFCoordinator, _LinkToken)

    ERC721(_name, _symbol) {

        // vrf stuff
        VRFCoordinator = _VRFCoordinator;
        LinkToken = _LinkToken;

        // erc721 stuff
        _contractURI = _contractMetaDataURI;
        keyHash = _keyHash;
        
        // set up the different redeption windows. 0 - ogs, 1 - earlybirds, 2 - ultimo macula, 3 - public.
        for(uint8 i = 0; i < _merkleRoots.length; i++) {
            redemptionWindows[i].open = false;
            redemptionWindows[i].maxRedeemPerWallet = _maxRedeemPerWallet[i];
            redemptionWindows[i].merkleRoot = _merkleRoots[i];
        }

        // setup rgb palette
        colours[0].push("#ff0000");
        colours[0].push("#00ff00");
        colours[0].push("#0000ff");
        colours[0].push("#ff8000");
        colours[0].push("#ffff00");
        colours[0].push("#ffffff");

        // setup cmyk palette
        colours[1].push("#ff00ff");
        colours[1].push("#00ffff");
        colours[1].push("#ffff00");
        colours[1].push("#000000");
        colours[1].push("#808080");
        colours[1].push("#ffffff");

        // setup b/w palette
        colours[2].push("#000000");
        colours[2].push("#333333");
        colours[2].push("#666666");
        colours[2].push("#999999");
        colours[2].push("#cccccc");
        colours[2].push("#ffffff");
    }

    /**
    * @notice Pause redeems until unpause is called. this pauses the whole contract. 
    */
    function pause() external override onlyOwner {
        _pause();
    }

    /**
    * @notice Unpause redeems until pause is called. this unpauses the whole contract. 
    */
    function unpause() external override onlyOwner {
        _unpause();
    }

    /**
    * @notice Set revealed to true. 
    */
    function reveal(bool state) external onlyOwner {
        revealed = state;
    }

    /**
    * @notice edit a redemption window. only writes value if it is different. 
    * 
    * @param _windowID the index of the claim window to set.
    * @param _merkleRoot the window merkleRoot.
    * @param _open the window open state.
    * @param _maxPerWallet the window maximum per wallet. 
    */
    function editRedemptionWindow(
        uint8 _windowID,
        bytes32 _merkleRoot, 
        bool _open,
        uint8 _maxPerWallet
    ) external override onlyOwner {
        if(redemptionWindows[_windowID].open != _open)
        {
            redemptionWindows[_windowID].open = _open;
        }
        if(redemptionWindows[_windowID].maxRedeemPerWallet != _maxPerWallet)
        {
            redemptionWindows[_windowID].maxRedeemPerWallet = _maxPerWallet;
        }
        if(redemptionWindows[_windowID].merkleRoot != _merkleRoot)
        {
            redemptionWindows[_windowID].merkleRoot = _merkleRoot;
        }
    }       

    /**
    * @notice Widthdraw Ether from contract.
    * 
    * @param _to the address to send to
    * @param _amount the amount to withdraw
    */
    function withdrawEther(address payable _to, uint256 _amount) public onlyOwner
    {
        _to.transfer(_amount);
    }

    /**
    * @notice Mint a Scramble.
    * 
    * @param windowIndex the index of the claim window to use.
    * @param amount the amount of tokens to mint
    * @param merkleProof the hash proving they are on the list for a given window. only applies to windows 0, 1 and 2.
    */
    function mint(uint8 windowIndex, uint8 amount, bytes32[] calldata merkleProof) external override{
        // checks
        require(redemptionWindows[windowIndex].open, "Redeem: window is not open");
        require(amount > 0, "Redeem: amount cannot be zero");
        require(amount < 11, "Redeem: amount cannot be more than 10");
        require(generalCounter.current() + amount <= MAX_MINT, "Max limit");

        if(windowIndex != 3)
        {
            // limit number that can be claimed for given presale window. 
            require(mintedTotal[msg.sender] + amount <=  redemptionWindows[windowIndex].maxRedeemPerWallet, "Too many for presale window");

            // check the merkle proof
            require(verifyMerkleProof(merkleProof, redemptionWindows[windowIndex].merkleRoot),"Invalid proof");          
        }

        string memory tokens = "";

        for(uint8 j = 0; j < amount; j++) {
            _safeMint(msg.sender, generalCounter.current());
            tokens = string(abi.encodePacked(tokens, generalCounter.current().toString(), ","));
            generalCounter.increment();
        }
        mintedTotal[msg.sender] = mintedTotal[msg.sender] + amount;
        emit Minted(msg.sender, tokens);
    }  

    /**
    * @notice Verify the merkle proof for a given root.   
    *     
    * @param proof vrf keyhash value
    * @param root vrf keyhash value
    */
    function verifyMerkleProof(bytes32[] memory proof, bytes32 root) public view returns (bool)
    {
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        return MerkleProof.verify(proof, root, leaf);
    }

    /**
    * @notice assign the returned chainlink vrf random number to baseSeed variable.   
    *     
    * @param requestId the id of the request - unused.
    * @param randomness the random number from chainlink vrf. 
    */
    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
        baseSeed = randomness;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721, ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
    }    

    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) {
        super._beforeTokenTransfer(from, to, tokenId);
    } 

    function setContractURI(string memory uri) external onlyOwner{
        _contractURI = uri;
    }

    function contractURI() public view returns (string memory) {
        return _contractURI;
    }

    /**
    * @notice returns the base64 encoded json metadata for a token.   
    *     
    * @param tokenId the token to return data for.
    */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        string memory name = string(abi.encodePacked("Scramble #", tokenId.toString()));
        return SVG721.metadata(name, getCoreNumbers(tokenId), getSVGString(tokenId),getTraits(tokenId));
    }

    /**
    * @notice returns the core numbers for the token. the palette index range:0-2 followed by the 9 colour indexes range: 0-5.
    *     
    * @param tokenId the tokenId to return numbers for.
    */
    function getCoreNumbers(uint256 tokenId) public view virtual override returns (string memory){
        string memory coreNumbers = "";

        if(!revealed)
        {
            return coreNumbers;
        }

        coreNumbers = string(abi.encodePacked(coreNumbers,getPaletteIndex(getSeed(tokenId)).toString()," "));

        for(uint8 i = 1; i < 10; i++)
        {
            coreNumbers = string(abi.encodePacked(coreNumbers,(expandRandom(getSeed(tokenId),i) % 6).toString()," "));
        }

        return coreNumbers;
    }

    /**
    * @notice checks if two indexes in a colour array match, if they do return 1 otherwise return 0.    
    *     
    * @param cols array of colours.
    * @param a first index to check.
    * @param b second index to check.
    */
    function checkConnection(string[9] memory cols, uint8 a, uint8 b) internal pure returns(uint8)
    {
        if(keccak256(abi.encodePacked(cols[a])) == keccak256(abi.encodePacked(cols[b]))){
            return 1;
        }
        else{
            return 0;
        }
    }

    /**
    * @notice returns the attributes part of the json string.   
    *     
    * @param tokenId the token to generate traits for.
    */
    function getTraits(uint256 tokenId) public view returns (string memory)
    {
        if(!revealed){
            return '"attributes": [{"value": "Unscrambled"}]';
        }

        string[9] memory cols;
        uint256[6] memory colTotals;

        for(uint8 j = 1; j < 10; j++) {
            
            string memory col = getColour(j,getSeed(tokenId));
            cols[j-1] =col; 

            for (uint i = 0; i<6; i++)
            {
                string memory colToCheck = colours[getPaletteIndex(getSeed(tokenId))][i];
                if(keccak256(abi.encodePacked(col)) == keccak256(abi.encodePacked(colToCheck)))
                {
                    colTotals[i]++;
                }
            }
        }

        uint8 connections = 0;

        connections += checkConnection(cols,0,1);
        connections += checkConnection(cols,1,2);
        connections += checkConnection(cols,0,3);
        connections += checkConnection(cols,1,4);
        connections += checkConnection(cols,2,5);
        connections += checkConnection(cols,3,4);
        connections += checkConnection(cols,4,5);
        connections += checkConnection(cols,3,6);
        connections += checkConnection(cols,4,7);
        connections += checkConnection(cols,5,8);
        connections += checkConnection(cols,6,7);
        connections += checkConnection(cols,7,8);

        uint256 totalCols = 0;

        for (uint256 h=0; h<6; h++){

            if(colTotals[h] > 0)
            {
                totalCols++;
            }
        }

        string memory traits = '"attributes": [';
        string memory newTrait = "";

        for (uint256 h = 0; h < 6; h++){
            string memory traitName = string(abi.encodePacked('Colour #', h.toString()));
            newTrait = getPropertyString(traitName,colTotals[h]);
            traits = string(abi.encodePacked(traits,newTrait,","));
        }

        newTrait = getPropertyString("Connections",connections);
        traits = string(abi.encodePacked(traits,newTrait,","));

        newTrait = getPropertyString("Palette",getPaletteIndex(getSeed(tokenId)));
        traits = string(abi.encodePacked(traits,newTrait,","));

        newTrait = getPropertyString("Total Colours",totalCols);
        traits = string(abi.encodePacked(traits,newTrait,","));

        newTrait = getLevelString("Background Colour",expandRandom(getSeed(tokenId),10) % 256);
        traits = string(abi.encodePacked(traits,newTrait,","));

        newTrait = getLevelString("Shirt Colour",expandRandom(getSeed(tokenId),11) % 256);
        traits = string(abi.encodePacked(traits,newTrait,"]"));

        return traits;
    }

    /**
    * @notice create a property string with value encased in quotes.    
    *
    * @param traitName the name of the trait
    * @param value the value of the trait
    */
    function getPropertyString(string memory traitName, uint256 value) internal pure returns (string memory)
    {
        return string(abi.encodePacked('{"trait_type": "',traitName,'" , "value": "',value.toString(),'"}'));
    }

    /**
    * @notice create a level string with value not encased in quotes.    
    *
    * @param traitName the name of the trait
    * @param value the value of the trait
    */
    function getLevelString(string memory traitName, uint256 value) internal pure returns (string memory)
    {
        return string(abi.encodePacked('{"trait_type": "',traitName,'" , "value": ',value.toString(),'}'));
    }

    /**
    * @notice Return the svg string for a given token.  
    *
    * @param tokenId the token to return.  
    */
    function getSVGString(uint256 tokenId) public view returns (string memory)
    {   
        if(!revealed){
            return "";
        }

        string memory svgPartOne = string(abi.encodePacked('<svg xmlns="http://www.w3.org/2000/svg" width="420" height="420">',
        string(abi.encodePacked('<rect width="420" height="420" x="0" y="0" fill=',getGrey(10,getSeed(tokenId),100),' />')),
        string(abi.encodePacked('<rect width="280" height="280" x="90" y="90" fill=',getGrey(10,getSeed(tokenId),66),' />')),
        string(abi.encodePacked('<rect width="280" height="280" x="80" y="80" fill=',getGrey(10,getSeed(tokenId),33),' />')),
        string(abi.encodePacked('<rect width="280" height="280" x="70" y="70" fill="#000000" />')),
        string(abi.encodePacked('<rect width="120" height="70" x="150" y="350" fill=',getGrey(11,getSeed(tokenId),100),' />'))));

        string memory svgPartTwo = string(abi.encodePacked(        
        string(abi.encodePacked('<rect width="10" height="50" x="170" y="370" fill="#000000" />')),
        string(abi.encodePacked('<rect width="10" height="50" x="240" y="370" fill="#000000" />')),
        string(abi.encodePacked('<rect width="80" height="80" x="80" y="80" fill="',getColour(1,getSeed(tokenId)),'" />')),
        string(abi.encodePacked('<rect width="80" height="80" x="170" y="80" fill="',getColour(2,getSeed(tokenId)),'" />')),
        string(abi.encodePacked('<rect width="80" height="80" x="260" y="80" fill="',getColour(3,getSeed(tokenId)),'" />'))));

        string memory svgPartThree = string(abi.encodePacked( 
        string(abi.encodePacked('<rect width="80" height="80" x="80" y="170" fill="',getColour(4,getSeed(tokenId)),'" />')),
        string(abi.encodePacked('<rect width="80" height="80" x="170" y="170" fill="',getColour(5,getSeed(tokenId)),'" />')),
        string(abi.encodePacked('<rect width="80" height="80" x="260" y="170" fill="',getColour(6,getSeed(tokenId)),'" />')),
        string(abi.encodePacked('<rect width="80" height="80" x="80" y="260" fill="',getColour(7,getSeed(tokenId)),'" />')),
        string(abi.encodePacked('<rect width="80" height="80" x="170" y="260" fill="',getColour(8,getSeed(tokenId)),'" />')),
        string(abi.encodePacked('<rect width="80" height="80" x="260" y="260" fill="',getColour(9,getSeed(tokenId)),'" />')),
        '</svg>'));

        return string(abi.encodePacked(svgPartOne,svgPartTwo,svgPartThree));
    }

    /**
    * @notice Return the palette index based on a seed.  
    *
    * @param colourIndex used to expand the random number.  
    * @param seed the seed for the token.  
    */
    function getColour(uint8 colourIndex, uint256 seed) internal view returns (string memory)
    {
        uint256 expandedVal = expandRandom(seed,colourIndex) % 6;
        return colours[getPaletteIndex(seed)][expandedVal];
    }

    /**
    * @notice Return the palette index based on a seed.  
    *
    * @param colourIndex used to expand the random number.  
    * @param seed the seed for the token.  
    * @param percentage used to create the shadows.  
    */
    function getGrey(uint8 colourIndex, uint256 seed, uint256 percentage) public pure returns (string memory)
    {
        uint256 grey = ((expandRandom(seed,colourIndex) % 256)*percentage)/100;
        return string(abi.encodePacked('"rgb(',grey.toString(),',',grey.toString(),',',grey.toString(),')"'));
    }

    /**
    * @notice Return the palette index based on a seed.  
    *
    * @param seed the seed for the token.  
    */
    function getPaletteIndex(uint256 seed) internal pure returns (uint8)
    {
        if (seed % 10 < 6){
            return 0;
        }
        else if (seed % 10 < 9){
            return 1;
        }
        else{
            return 2;
        }
    }

    /**
    * @notice Call chainlink to get a random number to use as the base for the random seeds.  
    *
    * @param fee the link fee.  
    */
    function scramble(uint256 fee) public onlyOwner returns (bytes32 requestId) {
        require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK");
        return requestRandomness(keyHash, fee);
    }

    /**
    * @notice Get the random seed for a given token, expanded from the baseSeed from Chainlink VRF. 
    * 
    * @param tokenId the token id 
    */
    function getSeed(uint256 tokenId) public view returns (uint256)
    {
        require(totalSupply()>tokenId, "Token Not Found");

        if (baseSeed == 0){
            return 0;
        }
        else{
            return expandRandom(baseSeed, tokenId);
        }
    }
    
    /**
    * @notice Get the random seed for a given token, expanded from the baseSeed from Chainlink VRF. 
    * 
    * @param random the base random number 
    * @param expansion the expansion number
    */
    function expandRandom(uint256 random, uint256 expansion) internal pure returns (uint256)
    {
        return uint256(keccak256(abi.encode(random, expansion))) % 2000000000;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8[]","name":"_maxRedeemPerWallet","type":"uint8[]"},{"internalType":"bytes32[]","name":"_merkleRoots","type":"bytes32[]"},{"internalType":"string","name":"_contractMetaDataURI","type":"string"},{"internalType":"address","name":"_VRFCoordinator","type":"address"},{"internalType":"address","name":"_LinkToken","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"string","name":"tokens","type":"string"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"LinkToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VRFCoordinator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":[],"name":"baseSeed","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":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"_windowID","type":"uint8"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"bool","name":"_open","type":"bool"},{"internalType":"uint8","name":"_maxPerWallet","type":"uint8"}],"name":"editRedemptionWindow","outputs":[],"stateMutability":"nonpayable","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":"getCoreNumbers","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"colourIndex","type":"uint8"},{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"name":"getGrey","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSVGString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSeed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTraits","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"uint8","name":"windowIndex","type":"uint8"},{"internalType":"uint8","name":"amount","type":"uint8"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintedTotal","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"redemptionWindows","outputs":[{"internalType":"bool","name":"open","type":"bool"},{"internalType":"uint8","name":"maxRedeemPerWallet","type":"uint8"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"uint256","name":"fee","type":"uint256"}],"name":"scramble","outputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setContractURI","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":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"verifyMerkleProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawEther","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040523480156200001157600080fd5b506040516200578f3803806200578f833981016040819052620000349162000b90565b8282898981600090805190602001906200005092919062000939565b5080516200006690600190602084019062000939565b5050600a805460ff19169055506200007e33620008df565b6001600160601b0319606092831b811660a052911b16608052600d80546001600160a01b038581166001600160a01b031992831617909255600e8054928516929091169190911790558351620000dc90601490602087019062000939565b50600f81905560005b85518160ff161015620001a45760ff81166000818152601160205260409020805460ff191690558751889190811062000122576200012262000d65565b60209081029190910181015160ff8084166000818152601190945260409093208054919092166101000261ff0019909116179055865187919081106200016c576200016c62000d65565b60209081029190910181015160ff831660009081526011909252604090912060010155806200019b8162000d36565b915050620000e5565b50601360209081526000805160206200576f8339815191528054600181018255600091909152604080518082019091526007808252660236666303030360cc1b919093019081526200020a926000805160206200572f8339815191529092019162000939565b50601360209081526000805160206200576f8339815191528054600181018255600091909152604080518082019091526007808252660233030666630360cc1b9190930190815262000270926000805160206200572f8339815191529092019162000939565b50601360209081526000805160206200576f8339815191528054600181018255600091909152604080518082019091526007808252661198181818333360c91b91909301908152620002d6926000805160206200572f8339815191529092019162000939565b50601360209081526000805160206200576f8339815191528054600181018255600091909152604080518082019091526007808252660236666383030360cc1b919093019081526200033c926000805160206200572f8339815191529092019162000939565b50601360209081526000805160206200576f8339815191528054600181018255600091909152604080518082019091526007808252660236666666630360cc1b91909301908152620003a2926000805160206200572f8339815191529092019162000939565b50601360209081526000805160206200576f83398151915280546001810182556000919091526040805180820190915260078082526611b3333333333360c91b9190930190815262000408926000805160206200572f8339815191529092019162000939565b5060136020908152600080516020620056ef83398151915280546001810182556000919091526040805180820190915260078082526611b3331818333360c91b919093019081526200046e926000805160206200574f8339815191529092019162000939565b5060136020908152600080516020620056ef8339815191528054600181018255600091909152604080518082019091526007808252661198183333333360c91b91909301908152620004d4926000805160206200574f8339815191529092019162000939565b5060136020908152600080516020620056ef8339815191528054600181018255600091909152604080518082019091526007808252660236666666630360cc1b919093019081526200053a926000805160206200574f8339815191529092019162000939565b5060136020908152600080516020620056ef8339815191528054600181018255600091909152604080518082019091526007808252660233030303030360cc1b91909301908152620005a0926000805160206200574f8339815191529092019162000939565b5060136020908152600080516020620056ef8339815191528054600181018255600091909152604080518082019091526007808252660233830383038360cc1b9190930190815262000606926000805160206200574f8339815191529092019162000939565b5060136020908152600080516020620056ef83398151915280546001810182556000919091526040805180820190915260078082526611b3333333333360c91b919093019081526200066c926000805160206200574f8339815191529092019162000939565b5060136020908152600080516020620056cf8339815191528054600181018255600091909152604080518082019091526007808252660233030303030360cc1b91909301908152620006d2926000805160206200570f8339815191529092019162000939565b5060136020908152600080516020620056cf8339815191528054600181018255600091909152604080518082019091526007808252662333333333333360c81b9190930190815262000738926000805160206200570f8339815191529092019162000939565b5060136020908152600080516020620056cf833981519152805460018101825560009190915260408051808201909152600780825266119b1b1b1b1b1b60c91b919093019081526200079e926000805160206200570f8339815191529092019162000939565b5060136020908152600080516020620056cf8339815191528054600181018255600091909152604080518082019091526007808252662339393939393960c81b9190930190815262000804926000805160206200570f8339815191529092019162000939565b5060136020908152600080516020620056cf8339815191528054600181018255600091909152604080518082019091526007808252662363636363636360c81b919093019081526200086a926000805160206200570f8339815191529092019162000939565b5060136020908152600080516020620056cf83398151915280546001810182556000919091526040805180820190915260078082526611b3333333333360c91b91909301908152620008d0926000805160206200570f8339815191529092019162000939565b50505050505050505062000d91565b600a80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620009479062000cf9565b90600052602060002090601f0160209004810192826200096b5760008555620009b6565b82601f106200098657805160ff1916838001178555620009b6565b82800160010185558215620009b6579182015b82811115620009b657825182559160200191906001019062000999565b50620009c4929150620009c8565b5090565b5b80821115620009c45760008155600101620009c9565b80516001600160a01b0381168114620009f757600080fd5b919050565b600082601f83011262000a0e57600080fd5b8151602062000a2762000a218362000cd3565b62000ca0565b80838252828201915082860187848660051b890101111562000a4857600080fd5b60005b8581101562000a695781518452928401929084019060010162000a4b565b5090979650505050505050565b600082601f83011262000a8857600080fd5b8151602062000a9b62000a218362000cd3565b80838252828201915082860187848660051b890101111562000abc57600080fd5b6000805b8681101562000aed57825160ff8116811462000ada578283fd5b8552938501939185019160010162000ac0565b509198975050505050505050565b600082601f83011262000b0d57600080fd5b81516001600160401b0381111562000b295762000b2962000d7b565b602062000b3f601f8301601f1916820162000ca0565b828152858284870101111562000b5457600080fd5b60005b8381101562000b7457858101830151828201840152820162000b57565b8381111562000b865760008385840101525b5095945050505050565b600080600080600080600080610100898b03121562000bae57600080fd5b88516001600160401b038082111562000bc657600080fd5b62000bd48c838d0162000afb565b995060208b015191508082111562000beb57600080fd5b62000bf98c838d0162000afb565b985060408b015191508082111562000c1057600080fd5b62000c1e8c838d0162000a76565b975060608b015191508082111562000c3557600080fd5b62000c438c838d01620009fc565b965060808b015191508082111562000c5a57600080fd5b5062000c698b828c0162000afb565b94505062000c7a60a08a01620009df565b925062000c8a60c08a01620009df565b915060e089015190509295985092959890939650565b604051601f8201601f191681016001600160401b038111828210171562000ccb5762000ccb62000d7b565b604052919050565b60006001600160401b0382111562000cef5762000cef62000d7b565b5060051b60200190565b600181811c9082168062000d0e57607f821691505b6020821081141562000d3057634e487b7160e01b600052602260045260246000fd5b50919050565b600060ff821660ff81141562000d5c57634e487b7160e01b600052601160045260246000fd5b60010192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60805160601c60a05160601c61490462000dcb6000396000818161152e01526128620152600081816110ff015261283301526149046000f3fe608060405234801561001057600080fd5b506004361061027f5760003560e01c80636603891c1161015c5780639e8ed6f7116100ce578063e0d4ea3711610087578063e0d4ea37146105af578063e1dc0761146105c2578063e8a3d485146105d5578063e985e9c5146105dd578063f0292a0314610619578063f2fde38b1461062257600080fd5b80639e8ed6f714610552578063a22cb4651461055b578063b88d4fde1461056e578063b91ca62214610581578063c0e7274014610594578063c87b56dd1461059c57600080fd5b80638456cb59116101205780638456cb59146104f35780638da5cb5b146104fb578063938e3d7b14610511578063940cd05b1461052457806394985ddd1461053757806395d89b411461054a57600080fd5b80636603891c1461049f5780636efc2e08146104b257806370a08231146104c557806370f53f75146104d8578063715018a6146104eb57600080fd5b806342842e0e116101f5578063522f6815116101b9578063522f6815146103f55780635602c675146104085780635c975abb1461041b5780635eac1378146104265780635f044052146104795780636352211e1461048c57600080fd5b806342842e0e1461039c57806342966c68146103af5780634f6ccce7146103c25780634f8e2fdf146103d557806351830227146103e857600080fd5b8063145f798f11610247578063145f798f1461031457806318160ddd1461034957806323b872dd1461035b5780632f745c591461036e57806333b60863146103815780633f4ba83a1461039457600080fd5b806301ffc9a71461028457806306fdde03146102ac578063081812fc146102c1578063095ea7b3146102ec57806312fc06a814610301575b600080fd5b6102976102923660046138b5565b610635565b60405190151581526020015b60405180910390f35b6102b4610646565b6040516102a39190614523565b6102d46102cf366004613938565b6106d8565b6040516001600160a01b0390911681526020016102a3565b6102ff6102fa366004613652565b610772565b005b6102b461030f366004613938565b610888565b610337610322366004613635565b60126020526000908152604090205460ff1681565b60405160ff90911681526020016102a3565b6008545b6040519081526020016102a3565b6102ff6103693660046136b7565b610ce2565b61034d61037c366004613652565b610d14565b600d546102d4906001600160a01b031681565b6102ff610daa565b6102ff6103aa3660046136b7565b610de4565b6102ff6103bd366004613938565b610dff565b61034d6103d0366004613938565b610e79565b600e546102d4906001600160a01b031681565b6015546102979060ff1681565b6102ff610403366004613652565b610f0c565b6102b46104163660046139d4565b610f72565b600a5460ff16610297565b61045a61043436600461396a565b6011602052600090815260409020805460019091015460ff808316926101009004169083565b60408051931515845260ff9092166020840152908201526060016102a3565b6102976104873660046137a6565b610ff0565b6102d461049a366004613938565b61103e565b61034d6104ad366004613938565b6110b5565b6102b46104c0366004613938565b6111d2565b61034d6104d3366004613635565b6112aa565b6102ff6104e6366004613985565b611331565b6102ff611427565b6102ff611461565b600a5461010090046001600160a01b03166102d4565b6102ff61051f3660046138ef565b611499565b6102ff610532366004613859565b6114e0565b6102ff610545366004613893565b611523565b6102b46115a1565b61034d60105481565b6102ff610569366004613778565b6115b0565b6102ff61057c3660046136f8565b6115bb565b6102ff61058f366004613a07565b6115ed565b6102b4611976565b6102b46105aa366004613938565b611a04565b61034d6105bd366004613938565b611a56565b6102b46105d0366004613938565b611abc565b6102b46120d0565b6102976105eb36600461367e565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61034d6103c381565b6102ff610630366004613635565b6120df565b60006106408261217d565b92915050565b60606000805461065590614715565b80601f016020809104026020016040519081016040528092919081815260200182805461068190614715565b80156106ce5780601f106106a3576101008083540402835291602001916106ce565b820191906000526020600020905b8154815290600101906020018083116106b157829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166107565760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061077d8261103e565b9050806001600160a01b0316836001600160a01b031614156107eb5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161074d565b336001600160a01b0382161480610807575061080781336105eb565b6108795760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161074d565b61088383836121a2565b505050565b60155460609060ff166108a957505060408051602081019091526000815290565b60006108c0600a6108b985611a56565b6064610f72565b6040516020016108d09190614383565b6040516020818303038152906040526108f4600a6108ed86611a56565b6042610f72565b6040516020016109049190614330565b604051602081830303815290604052610928600a61092187611a56565b6021610f72565b60405160200161093891906142c3565b6040516020818303038152906040526040516020016109a0907f3c726563742077696474683d2232383022206865696768743d2232383022207881527f3d2237302220793d223730222066696c6c3d222330303030303022202f3e00006020820152603e0190565b6040516020818303038152906040526109bd600b6108b989611a56565b6040516020016109cd9190613f35565b60408051601f19818403018152908290526109ee95949392916020016143ee565b60405160208183030381529060405290506000604051602001610a5a907f3c726563742077696474683d22313022206865696768743d2235302220783d2281527f3137302220793d22333730222066696c6c3d222330303030303022202f3e00006020820152603e0190565b604051602081830303815290604052604051602001610ac2907f3c726563742077696474683d22313022206865696768743d2235302220783d2281527f3234302220793d22333730222066696c6c3d222330303030303022202f3e00006020820152603e0190565b604051602081830303815290604052610ae46001610adf88611a56565b612210565b604051602001610af4919061416f565b604051602081830303815290604052610b116002610adf89611a56565b604051602001610b219190614250565b604051602081830303815290604052610b3e6003610adf8a611a56565b604051602001610b4e91906141ca565b60408051601f1981840301815290829052610b6f9594939291602001613b23565b60405160208183030381529060405290506000610b906004610adf87611a56565b604051602001610ba09190613fa3565b604051602081830303815290604052610bbd6005610adf88611a56565b604051602001610bcd9190614070565b604051602081830303815290604052610bea6006610adf89611a56565b604051602001610bfa9190613ef3565b604051602081830303815290604052610c176007610adf8a611a56565b604051602001610c279190613fff565b604051602081830303815290604052610c446008610adf8b611a56565b604051602001610c5491906140b2565b604051602081830303815290604052610c716009610adf8c611a56565b604051602001610c819190613ccc565b60408051601f1981840301815290829052610ca3969594939291602001613b8e565b6040516020818303038152906040529050828282604051602001610cc993929190613ae0565b6040516020818303038152906040529350505050919050565b610ced335b826122fd565b610d095760405162461bcd60e51b815260040161074d906145bd565b6108838383836123f0565b6000610d1f836112aa565b8210610d815760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161074d565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b03610100909104163314610dda5760405162461bcd60e51b815260040161074d90614588565b610de261259b565b565b610883838383604051806020016040528060008152506115bb565b610e0833610ce7565b610e6d5760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b606482015260840161074d565b610e768161262e565b50565b6000610e8460085490565b8210610ee75760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161074d565b60088281548110610efa57610efa6147e1565b90600052602060002001549050919050565b600a546001600160a01b03610100909104163314610f3c5760405162461bcd60e51b815260040161074d90614588565b6040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015610883573d6000803e3d6000fd5b60606000606483610100610f89878960ff166126d5565b610f93919061478b565b610f9d9190614690565b610fa7919061467c565b9050610fb28161271b565b610fbb8261271b565b610fc48361271b565b604051602001610fd6939291906140f4565b6040516020818303038152906040529150505b9392505050565b6040516bffffffffffffffffffffffff193360601b1660208201526000908190603401604051602081830303815290604052805190602001209050611036848483612819565b949350505050565b6000818152600260205260408120546001600160a01b0316806106405760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161074d565b600a546000906001600160a01b036101009091041633146110e85760405162461bcd60e51b815260040161074d90614588565b6040516370a0823160e01b815230600482015282907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b15801561114957600080fd5b505afa15801561115d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111819190613951565b10156111c15760405162461bcd60e51b815260206004820152600f60248201526e4e6f7420656e6f756768204c494e4b60881b604482015260640161074d565b610640600f548361282f565b919050565b6040805160208101909152600081526015546060919060ff166111f55792915050565b8061121261120a61120586611a56565b6129ba565b60ff1661271b565b604051602001611223929190613c56565b60408051601f19818403018152919052905060015b600a8160ff1610156112a3578161126e600661125f61125688611a56565b8560ff166126d5565b611269919061478b565b61271b565b60405160200161127f929190613c56565b6040516020818303038152906040529150808061129b9061476b565b915050611238565b5092915050565b60006001600160a01b0382166113155760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161074d565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b036101009091041633146113615760405162461bcd60e51b815260040161074d90614588565b60ff8085166000908152601160205260409020541615158215151461139f5760ff84166000908152601160205260409020805460ff19168315151790555b60ff84811660009081526011602052604090205461010090048116908216146113ec5760ff808516600090815260116020526040902080549183166101000261ff00199092169190911790555b60ff841660009081526011602052604090206001015483146114215760ff841660009081526011602052604090206001018390555b50505050565b600a546001600160a01b036101009091041633146114575760405162461bcd60e51b815260040161074d90614588565b610de260006129fa565b600a546001600160a01b036101009091041633146114915760405162461bcd60e51b815260040161074d90614588565b610de2612a54565b600a546001600160a01b036101009091041633146114c95760405162461bcd60e51b815260040161074d90614588565b80516114dc9060149060208401906134ed565b5050565b600a546001600160a01b036101009091041633146115105760405162461bcd60e51b815260040161074d90614588565b6015805460ff1916911515919091179055565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461159b5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c00604482015260640161074d565b60105550565b60606001805461065590614715565b6114dc338383612acf565b6115c533836122fd565b6115e15760405162461bcd60e51b815260040161074d906145bd565b61142184848484612b9e565b60ff8085166000908152601160205260409020541661164e5760405162461bcd60e51b815260206004820152601a60248201527f52656465656d3a2077696e646f77206973206e6f74206f70656e000000000000604482015260640161074d565b60008360ff16116116a15760405162461bcd60e51b815260206004820152601d60248201527f52656465656d3a20616d6f756e742063616e6e6f74206265207a65726f000000604482015260640161074d565b600b8360ff16106117025760405162461bcd60e51b815260206004820152602560248201527f52656465656d3a20616d6f756e742063616e6e6f74206265206d6f72652074686044820152640616e2031360dc1b606482015260840161074d565b6103c38360ff16611712600c5490565b61171c919061463f565b11156117565760405162461bcd60e51b815260206004820152600960248201526813585e081b1a5b5a5d60ba1b604482015260640161074d565b8360ff166003146118755760ff80851660009081526011602090815260408083205433845260129092529091205461010090910482169161179991869116614657565b60ff1611156117ea5760405162461bcd60e51b815260206004820152601b60248201527f546f6f206d616e7920666f722070726573616c652077696e646f770000000000604482015260640161074d565b611839828280806020026020016040519081016040528093929190818152602001838360200280828437600092018290525060ff8a168152601160205260409020600101549250610ff0915050565b6118755760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b604482015260640161074d565b604080516020810190915260008082525b8460ff168160ff1610156118f5576118a6336118a1600c5490565b612bd1565b816118b3611269600c5490565b6040516020016118c4929190613c1b565b60405160208183030381529060405291506118e3600c80546001019055565b806118ed8161476b565b915050611886565b503360009081526012602052604090205461191490859060ff16614657565b3360008181526012602052604090819020805460ff191660ff949094169390931790925590517f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f9290611967908490614523565b60405180910390a25050505050565b6014805461198390614715565b80601f01602080910402602001604051908101604052809291908181526020018280546119af90614715565b80156119fc5780601f106119d1576101008083540402835291602001916119fc565b820191906000526020600020905b8154815290600101906020018083116119df57829003601f168201915b505050505081565b60606000611a118361271b565b604051602001611a219190614291565b6040516020818303038152906040529050610fe981611a3f856111d2565b611a4886610888565b611a5187611abc565b612beb565b600081611a6260085490565b11611aa15760405162461bcd60e51b815260206004820152600f60248201526e151bdad95b88139bdd08119bdd5b99608a1b604482015260640161074d565b601054611ab057506000919050565b610640601054836126d5565b60155460609060ff16611ae8576040518060600160405280602881526020016148876028913992915050565b611af0613571565b611af8613599565b60015b600a8160ff161015611cb7576000611b1682610adf88611a56565b90508084611b256001856146c6565b60ff1660098110611b3857611b386147e1565b602002015260005b6006811015611ca257600060136000611b5b6112058b611a56565b60ff1660ff1681526020019081526020016000208281548110611b8057611b806147e1565b906000526020600020018054611b9590614715565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc190614715565b8015611c0e5780601f10611be357610100808354040283529160200191611c0e565b820191906000526020600020905b815481529060010190602001808311611bf157829003601f168201915b5050505050905080604051602001611c269190613ac4565b6040516020818303038152906040528051906020012083604051602001611c4d9190613ac4565b604051602081830303815290604052805190602001201415611c8f57848260068110611c7b57611c7b6147e1565b60200201805190611c8b82614750565b9052505b5080611c9a81614750565b915050611b40565b50508080611caf9061476b565b915050611afb565b506000611cc78360006001612c52565b611cd19082614657565b9050611ce08360016002612c52565b611cea9082614657565b9050611cf98360006003612c52565b611d039082614657565b9050611d128360016004612c52565b611d1c9082614657565b9050611d2b8360026005612c52565b611d359082614657565b9050611d448360036004612c52565b611d4e9082614657565b9050611d5d8360046005612c52565b611d679082614657565b9050611d768360036006612c52565b611d809082614657565b9050611d8f8360046007612c52565b611d999082614657565b9050611da88360056008612c52565b611db29082614657565b9050611dc18360066007612c52565b611dcb9082614657565b9050611dda8360076008612c52565b611de49082614657565b90506000805b6006811015611e32576000848260068110611e0757611e076147e1565b60200201511115611e205781611e1c81614750565b9250505b80611e2a81614750565b915050611dea565b50604080518082018252600f81526e2261747472696275746573223a205b60881b602080830191909152825190810190925260008083529091905b6006811015611efc576000611e818261271b565b604051602001611e919190614040565b6040516020818303038152906040529050611ec281888460068110611eb857611eb86147e1565b6020020151612cea565b92508383604051602001611ed7929190613c1b565b6040516020818303038152906040529350508080611ef490614750565b915050611e6d565b50611f2d6040518060400160405280600b81526020016a436f6e6e656374696f6e7360a81b8152508560ff16612cea565b90508181604051602001611f42929190613c1b565b60408051601f19818403018152828201909152600782526650616c6574746560c81b60208301529250611f8390611f7b6112058b611a56565b60ff16612cea565b90508181604051602001611f98929190613c1b565b60408051601f19818403018152828201909152600d82526c546f74616c20436f6c6f75727360981b60208301529250611fd19084612cea565b90508181604051602001611fe6929190613c1b565b60408051601f1981840301815282820190915260118252702130b1b5b3b937bab7321021b7b637bab960791b602083015292506120429061010061203361202c8c611a56565b600a6126d5565b61203d919061478b565b612d1e565b90508181604051602001612057929190613c1b565b60408051601f19818403018152828201909152600c82526b29b434b93a1021b7b637bab960a11b6020830152925061209f906101006120336120988c611a56565b600b6126d5565b905081816040516020016120b4929190613c91565b60408051601f1981840301815291905298975050505050505050565b60606014805461065590614715565b600a546001600160a01b0361010090910416331461210f5760405162461bcd60e51b815260040161074d90614588565b6001600160a01b0381166121745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161074d565b610e76816129fa565b60006001600160e01b0319821663780e9d6360e01b1480610640575061064082612d3b565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906121d78261103e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b606060006006612223848660ff166126d5565b61222d919061478b565b90506013600061223c856129ba565b60ff1660ff1681526020019081526020016000208181548110612261576122616147e1565b90600052602060002001805461227690614715565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614715565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b505050505091505092915050565b6000818152600260205260408120546001600160a01b03166123765760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161074d565b60006123818361103e565b9050806001600160a01b0316846001600160a01b031614806123bc5750836001600160a01b03166123b1846106d8565b6001600160a01b0316145b8061103657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff16611036565b826001600160a01b03166124038261103e565b6001600160a01b03161461246b5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161074d565b6001600160a01b0382166124cd5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161074d565b6124d8838383612d8b565b6124e36000826121a2565b6001600160a01b038316600090815260036020526040812080546001929061250c9084906146af565b90915550506001600160a01b038216600090815260036020526040812080546001929061253a90849061463f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a5460ff166125e45760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161074d565b600a805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60006126398261103e565b905061264781600084612d8b565b6126526000836121a2565b6001600160a01b038116600090815260036020526040812080546001929061267b9084906146af565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000637735940083836040516020016126f8929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c610fe9919061478b565b60608161273f5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612769578061275381614750565b91506127629050600a8361467c565b9150612743565b60008167ffffffffffffffff811115612784576127846147f7565b6040519080825280601f01601f1916602001820160405280156127ae576020820181803683370190505b5090505b8415611036576127c36001836146af565b91506127d0600a8661478b565b6127db90603061463f565b60f81b8183815181106127f0576127f06147e1565b60200101906001600160f81b031916908160001a905350612812600a8661467c565b94506127b2565b6000826128268584612d96565b14949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f00000000000000000000000000000000000000000000000000000000000000008486600060405160200161289f929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016128cc939291906144f3565b602060405180830381600087803b1580156128e657600080fd5b505af11580156128fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061291e9190613876565b506000838152600b6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a09091019092528151918301919091209387905291905261297a90600161463f565b6000858152600b60205260409020556110368482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600060066129c9600a8461478b565b10156129d757506000919050565b60096129e4600a8461478b565b10156129f257506001919050565b506002919050565b600a80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a5460ff1615612a9a5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161074d565b600a805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586126113390565b816001600160a01b0316836001600160a01b03161415612b315760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161074d565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612ba98484846123f0565b612bb584848484612e42565b6114215760405162461bcd60e51b815260040161074d90614536565b6114dc828260405180602001604052806000815250612f4c565b606060008585612bfa86612f7f565b85604051602001612c0e9493929190613e11565b6040516020818303038152906040529050612c2881612f7f565b604051602001612c38919061420b565b604051602081830303815290604052915050949350505050565b6000838260ff1660098110612c6957612c696147e1565b6020020151604051602001612c7e9190613ac4565b60405160208183030381529060405280519060200120848460ff1660098110612ca957612ca96147e1565b6020020151604051602001612cbe9190613ac4565b604051602081830303815290604052805190602001201415612ce257506001610fe9565b506000610fe9565b606082612cf68361271b565b604051602001612d07929190613d29565b604051602081830303815290604052905092915050565b606082612d2a8361271b565b604051602001612d07929190613d9e565b60006001600160e01b031982166380ac58cd60e01b1480612d6c57506001600160e01b03198216635b5e139f60e01b145b8061064057506301ffc9a760e01b6001600160e01b0319831614610640565b6108838383836130e5565b600081815b8451811015612e3a576000858281518110612db857612db86147e1565b60200260200101519050808311612dfa576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250612e27565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b5080612e3281614750565b915050612d9b565b509392505050565b60006001600160a01b0384163b15612f4457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612e869033908990889088906004016144b6565b602060405180830381600087803b158015612ea057600080fd5b505af1925050508015612ed0575060408051601f3d908101601f19168201909252612ecd918101906138d2565b60015b612f2a573d808015612efe576040519150601f19603f3d011682016040523d82523d6000602084013e612f03565b606091505b508051612f225760405162461bcd60e51b815260040161074d90614536565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611036565b506001611036565b612f568383613157565b612f636000848484612e42565b6108835760405162461bcd60e51b815260040161074d90614536565b805160609080612f9f575050604080516020810190915260008152919050565b60006003612fae83600261463f565b612fb8919061467c565b612fc3906004614690565b90506000612fd282602061463f565b67ffffffffffffffff811115612fea57612fea6147f7565b6040519080825280601f01601f191660200182016040528015613014576020820181803683370190505b5090506000604051806060016040528060408152602001614847604091399050600181016020830160005b868110156130a0576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b83526004909201910161303f565b5060038606600181146130ba57600281146130cb576130d7565b613d3d60f01b6001198301526130d7565b603d60f81b6000198301525b505050918152949350505050565b6130f08383836132a5565b600a5460ff16156108835760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201526a1a1a5b19481c185d5cd95960aa1b606482015260840161074d565b6001600160a01b0382166131ad5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161074d565b6000818152600260205260409020546001600160a01b0316156132125760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161074d565b61321e60008383612d8b565b6001600160a01b038216600090815260036020526040812080546001929061324790849061463f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b038316613300576132fb81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613323565b816001600160a01b0316836001600160a01b03161461332357613323838261335d565b6001600160a01b03821661333a57610883816133fa565b826001600160a01b0316826001600160a01b0316146108835761088382826134a9565b6000600161336a846112aa565b61337491906146af565b6000838152600760205260409020549091508082146133c7576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061340c906001906146af565b60008381526009602052604081205460088054939450909284908110613434576134346147e1565b906000526020600020015490508060088381548110613455576134556147e1565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061348d5761348d6147cb565b6001900381819060005260206000200160009055905550505050565b60006134b4836112aa565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b8280546134f990614715565b90600052602060002090601f01602090048101928261351b5760008555613561565b82601f1061353457805160ff1916838001178555613561565b82800160010185558215613561579182015b82811115613561578251825591602001919060010190613546565b5061356d9291506135b7565b5090565b6040518061012001604052806009905b60608152602001906001900390816135815790505090565b6040518060c001604052806006906020820280368337509192915050565b5b8082111561356d57600081556001016135b8565b600067ffffffffffffffff8311156135e6576135e66147f7565b6135f9601f8401601f191660200161460e565b905082815283838301111561360d57600080fd5b828260208301376000602084830101529392505050565b803560ff811681146111cd57600080fd5b60006020828403121561364757600080fd5b8135610fe98161480d565b6000806040838503121561366557600080fd5b82356136708161480d565b946020939093013593505050565b6000806040838503121561369157600080fd5b823561369c8161480d565b915060208301356136ac8161480d565b809150509250929050565b6000806000606084860312156136cc57600080fd5b83356136d78161480d565b925060208401356136e78161480d565b929592945050506040919091013590565b6000806000806080858703121561370e57600080fd5b84356137198161480d565b935060208501356137298161480d565b925060408501359150606085013567ffffffffffffffff81111561374c57600080fd5b8501601f8101871361375d57600080fd5b61376c878235602084016135cc565b91505092959194509250565b6000806040838503121561378b57600080fd5b82356137968161480d565b915060208301356136ac81614822565b600080604083850312156137b957600080fd5b823567ffffffffffffffff808211156137d157600080fd5b818501915085601f8301126137e557600080fd5b81356020828211156137f9576137f96147f7565b8160051b925061380a81840161460e565b8281528181019085830185870184018b101561382557600080fd5b600096505b8487101561384857803583526001969096019591830191830161382a565b509997909101359750505050505050565b60006020828403121561386b57600080fd5b8135610fe981614822565b60006020828403121561388857600080fd5b8151610fe981614822565b600080604083850312156138a657600080fd5b50508035926020909101359150565b6000602082840312156138c757600080fd5b8135610fe981614830565b6000602082840312156138e457600080fd5b8151610fe981614830565b60006020828403121561390157600080fd5b813567ffffffffffffffff81111561391857600080fd5b8201601f8101841361392957600080fd5b611036848235602084016135cc565b60006020828403121561394a57600080fd5b5035919050565b60006020828403121561396357600080fd5b5051919050565b60006020828403121561397c57600080fd5b610fe982613624565b6000806000806080858703121561399b57600080fd5b6139a485613624565b93506020850135925060408501356139bb81614822565b91506139c960608601613624565b905092959194509250565b6000806000606084860312156139e957600080fd5b6139f284613624565b95602085013595506040909401359392505050565b60008060008060608587031215613a1d57600080fd5b613a2685613624565b9350613a3460208601613624565b9250604085013567ffffffffffffffff80821115613a5157600080fd5b818701915087601f830112613a6557600080fd5b813581811115613a7457600080fd5b8860208260051b8501011115613a8957600080fd5b95989497505060200194505050565b60008151808452613ab08160208601602086016146e9565b601f01601f19169290920160200192915050565b60008251613ad68184602087016146e9565b9190910192915050565b60008451613af28184602089016146e9565b845190830190613b068183602089016146e9565b8451910190613b198183602088016146e9565b0195945050505050565b60008651613b35818460208b016146e9565b865190830190613b49818360208b016146e9565b8651910190613b5c818360208a016146e9565b8551910190613b6f8183602089016146e9565b8451910190613b828183602088016146e9565b01979650505050505050565b600087516020613ba18285838d016146e9565b885191840191613bb48184848d016146e9565b8851920191613bc68184848c016146e9565b8751920191613bd88184848b016146e9565b8651920191613bea8184848a016146e9565b8551920191613bfc81848489016146e9565b651e17b9bb339f60d11b92019182525060060198975050505050505050565b60008351613c2d8184602088016146e9565b835190830190613c418183602088016146e9565b600b60fa1b9101908152600101949350505050565b60008351613c688184602088016146e9565b835190830190613c7c8183602088016146e9565b600160fd1b9101908152600101949350505050565b60008351613ca38184602088016146e9565b835190830190613cb78183602088016146e9565b605d60f81b9101908152600101949350505050565b6000805160206148af833981519152815272191b1811103c9e91191b1811103334b6361e9160691b602082015260008251613d0e8160338501602087016146e9565b631110179f60e11b6033939091019283015250603701919050565b6f3d913a3930b4ba2fba3cb832911d101160811b81528251600090613d558160108501602088016146e9565b6d11101610113b30b63ab2911d101160911b6010918401918201528351613d8381601e8401602088016146e9565b61227d60f01b601e9290910191820152602001949350505050565b6f3d913a3930b4ba2fba3cb832911d101160811b81528251600090613dca8160108501602088016146e9565b6c011101610113b30b63ab2911d1609d1b6010918401918201528351613df781601d8401602088016146e9565b607d60f81b601d9290910191820152601e01949350505050565b683d913730b6b2911d1160b91b81528451600090613e36816009850160208a016146e9565b701116113232b9b1b934b83a34b7b7111d1160791b6009918401918201528551613e6781601a840160208a016146e9565b7f222c22696d616765223a2022646174613a696d6167652f7376672b786d6c3b62601a929091019182015265185cd94d8d0b60d21b603a8201528451613eb48160408401602089016146e9565b61088b60f21b604092909101918201528351613ed78160428401602088016146e9565b607d60f81b604292909101918201526043019695505050505050565b6000805160206148af833981519152815272191b1811103c9e91189b9811103334b6361e9160691b602082015260008251613d0e8160338501602087016146e9565b7f3c726563742077696474683d2231323022206865696768743d2237302220783d815272223135302220793d22333530222066696c6c3d60681b602082015260008251613f898160338501602087016146e9565b6210179f60e91b6033939091019283015250603601919050565b6000805160206148af8339815191528152711c1811103c9e91189b9811103334b6361e9160711b602082015260008251613fe48160328501602087016146e9565b631110179f60e11b6032939091019283015250603601919050565b6000805160206148af8339815191528152711c1811103c9e91191b1811103334b6361e9160711b602082015260008251613fe48160328501602087016146e9565b67436f6c6f7572202360c01b8152600082516140638160088501602087016146e9565b9190910160080192915050565b6000805160206148af833981519152815272189b9811103c9e91189b9811103334b6361e9160691b602082015260008251613d0e8160338501602087016146e9565b6000805160206148af833981519152815272189b9811103c9e91191b1811103334b6361e9160691b602082015260008251613d0e8160338501602087016146e9565b64044e4cec4560db1b815283516000906141158160058501602089016146e9565b8083019050600b60fa1b8060058301528551614138816006850160208a016146e9565b600692019182015283516141538160078401602088016146e9565b61149160f11b6007929091019182015260090195945050505050565b6000805160206148af8339815191528152701c1811103c9e911c1811103334b6361e9160791b6020820152600082516141af8160318501602087016146e9565b631110179f60e11b6031939091019283015250603501919050565b6000805160206148af833981519152815271191b1811103c9e911c1811103334b6361e9160711b602082015260008251613fe48160328501602087016146e9565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161424381601d8501602087016146e9565b91909101601d0192915050565b6000805160206148af833981519152815271189b9811103c9e911c1811103334b6361e9160711b602082015260008251613fe48160328501602087016146e9565b69536372616d626c65202360b01b8152600082516142b681600a8501602087016146e9565b91909101600a0192915050565b7f3c726563742077696474683d2232383022206865696768743d223238302220788152713d2238302220793d223830222066696c6c3d60701b6020820152600082516143168160328501602087016146e9565b6210179f60e91b6032939091019283015250603501919050565b7f3c726563742077696474683d2232383022206865696768743d223238302220788152713d2239302220793d223930222066696c6c3d60701b6020820152600082516143168160328501602087016146e9565b7f3c726563742077696474683d2234323022206865696768743d2234323022207881526f3d22302220793d2230222066696c6c3d60801b6020820152600082516143d48160308501602087016146e9565b6210179f60e91b6030939091019283015250603301919050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f32308152600060207f30302f737667222077696474683d2234323022206865696768743d223432302281840152601f60f91b60408401526041885161445781838701858d016146e9565b88519085019061446c81848401868d016146e9565b885191019061448081848401868c016146e9565b875191019061449481848401868b016146e9565b86519101906144a881848401868a016146e9565b010198975050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906144e990830184613a98565b9695505050505050565b60018060a01b038416815282602082015260606040820152600061451a6060830184613a98565b95945050505050565b602081526000610fe96020830184613a98565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715614637576146376147f7565b604052919050565b600082198211156146525761465261479f565b500190565b600060ff821660ff84168060ff038211156146745761467461479f565b019392505050565b60008261468b5761468b6147b5565b500490565b60008160001904831182151516156146aa576146aa61479f565b500290565b6000828210156146c1576146c161479f565b500390565b600060ff821660ff8416808210156146e0576146e061479f565b90039392505050565b60005b838110156147045781810151838201526020016146ec565b838111156114215750506000910152565b600181811c9082168061472957607f821691505b6020821081141561474a57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156147645761476461479f565b5060010190565b600060ff821660ff8114156147825761478261479f565b60010192915050565b60008261479a5761479a6147b5565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610e7657600080fd5b8015158114610e7657600080fd5b6001600160e01b031981168114610e7657600080fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f2261747472696275746573223a205b7b2276616c7565223a2022556e736372616d626c6564227d5d3c726563742077696474683d22383022206865696768743d2238302220783d22a2646970667358221220183c932e9248e9bc2474e40669e0d603165095cbea4b6cbfa8ac3c65a8ca66ed64736f6c634300080700330b9d2c0c271bb30544eb78c59bdaebdae2728e5f65814c07768a0abe90ed19234155c2f711f2cdd34f8262ab8fb9b7020a700fe7b6948222152f7670d1fdf34d354da2bfe7dc0787dd5fdc6ce69d9d3628f19c1d4b862d540ce8326263f2b6e4fdad409e641dc7bad299410a553e45a22a0e8938c35e57d79a499ceca456678a3ce2cb385edcbf7185fd469186dd769993781141b215a1a4715ebb7f94fd59ab8fa6efc3be94b5b348b21fea823fe8d100408cee9b7f90524494500445d8ff6c000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986caaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af4450000000000000000000000000000000000000000000000000000000000000009536372616d626c6573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045343524d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000041f707fa87cca6d5e52f76e8fbf0ecb9130818402856cf57b32be54af249473469c7ac34dd9c8380d4dc0bed49bdb8fbba354a19a9088370869ea90513e6d192c485a5f2f27d6d6755110bd308edda7118fbcba62507b7758617256f8a535de7b1e0fa23b9aeab82ec0dd34d09000e75c6fd16dccda9c8d2694ecd4f190213f45000000000000000000000000000000000000000000000000000000000000005068747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d58714c754a72786b78616d617373525157434e5641625a474e685253777338424d6d32794a397339354b414400000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061027f5760003560e01c80636603891c1161015c5780639e8ed6f7116100ce578063e0d4ea3711610087578063e0d4ea37146105af578063e1dc0761146105c2578063e8a3d485146105d5578063e985e9c5146105dd578063f0292a0314610619578063f2fde38b1461062257600080fd5b80639e8ed6f714610552578063a22cb4651461055b578063b88d4fde1461056e578063b91ca62214610581578063c0e7274014610594578063c87b56dd1461059c57600080fd5b80638456cb59116101205780638456cb59146104f35780638da5cb5b146104fb578063938e3d7b14610511578063940cd05b1461052457806394985ddd1461053757806395d89b411461054a57600080fd5b80636603891c1461049f5780636efc2e08146104b257806370a08231146104c557806370f53f75146104d8578063715018a6146104eb57600080fd5b806342842e0e116101f5578063522f6815116101b9578063522f6815146103f55780635602c675146104085780635c975abb1461041b5780635eac1378146104265780635f044052146104795780636352211e1461048c57600080fd5b806342842e0e1461039c57806342966c68146103af5780634f6ccce7146103c25780634f8e2fdf146103d557806351830227146103e857600080fd5b8063145f798f11610247578063145f798f1461031457806318160ddd1461034957806323b872dd1461035b5780632f745c591461036e57806333b60863146103815780633f4ba83a1461039457600080fd5b806301ffc9a71461028457806306fdde03146102ac578063081812fc146102c1578063095ea7b3146102ec57806312fc06a814610301575b600080fd5b6102976102923660046138b5565b610635565b60405190151581526020015b60405180910390f35b6102b4610646565b6040516102a39190614523565b6102d46102cf366004613938565b6106d8565b6040516001600160a01b0390911681526020016102a3565b6102ff6102fa366004613652565b610772565b005b6102b461030f366004613938565b610888565b610337610322366004613635565b60126020526000908152604090205460ff1681565b60405160ff90911681526020016102a3565b6008545b6040519081526020016102a3565b6102ff6103693660046136b7565b610ce2565b61034d61037c366004613652565b610d14565b600d546102d4906001600160a01b031681565b6102ff610daa565b6102ff6103aa3660046136b7565b610de4565b6102ff6103bd366004613938565b610dff565b61034d6103d0366004613938565b610e79565b600e546102d4906001600160a01b031681565b6015546102979060ff1681565b6102ff610403366004613652565b610f0c565b6102b46104163660046139d4565b610f72565b600a5460ff16610297565b61045a61043436600461396a565b6011602052600090815260409020805460019091015460ff808316926101009004169083565b60408051931515845260ff9092166020840152908201526060016102a3565b6102976104873660046137a6565b610ff0565b6102d461049a366004613938565b61103e565b61034d6104ad366004613938565b6110b5565b6102b46104c0366004613938565b6111d2565b61034d6104d3366004613635565b6112aa565b6102ff6104e6366004613985565b611331565b6102ff611427565b6102ff611461565b600a5461010090046001600160a01b03166102d4565b6102ff61051f3660046138ef565b611499565b6102ff610532366004613859565b6114e0565b6102ff610545366004613893565b611523565b6102b46115a1565b61034d60105481565b6102ff610569366004613778565b6115b0565b6102ff61057c3660046136f8565b6115bb565b6102ff61058f366004613a07565b6115ed565b6102b4611976565b6102b46105aa366004613938565b611a04565b61034d6105bd366004613938565b611a56565b6102b46105d0366004613938565b611abc565b6102b46120d0565b6102976105eb36600461367e565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61034d6103c381565b6102ff610630366004613635565b6120df565b60006106408261217d565b92915050565b60606000805461065590614715565b80601f016020809104026020016040519081016040528092919081815260200182805461068190614715565b80156106ce5780601f106106a3576101008083540402835291602001916106ce565b820191906000526020600020905b8154815290600101906020018083116106b157829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166107565760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061077d8261103e565b9050806001600160a01b0316836001600160a01b031614156107eb5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161074d565b336001600160a01b0382161480610807575061080781336105eb565b6108795760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161074d565b61088383836121a2565b505050565b60155460609060ff166108a957505060408051602081019091526000815290565b60006108c0600a6108b985611a56565b6064610f72565b6040516020016108d09190614383565b6040516020818303038152906040526108f4600a6108ed86611a56565b6042610f72565b6040516020016109049190614330565b604051602081830303815290604052610928600a61092187611a56565b6021610f72565b60405160200161093891906142c3565b6040516020818303038152906040526040516020016109a0907f3c726563742077696474683d2232383022206865696768743d2232383022207881527f3d2237302220793d223730222066696c6c3d222330303030303022202f3e00006020820152603e0190565b6040516020818303038152906040526109bd600b6108b989611a56565b6040516020016109cd9190613f35565b60408051601f19818403018152908290526109ee95949392916020016143ee565b60405160208183030381529060405290506000604051602001610a5a907f3c726563742077696474683d22313022206865696768743d2235302220783d2281527f3137302220793d22333730222066696c6c3d222330303030303022202f3e00006020820152603e0190565b604051602081830303815290604052604051602001610ac2907f3c726563742077696474683d22313022206865696768743d2235302220783d2281527f3234302220793d22333730222066696c6c3d222330303030303022202f3e00006020820152603e0190565b604051602081830303815290604052610ae46001610adf88611a56565b612210565b604051602001610af4919061416f565b604051602081830303815290604052610b116002610adf89611a56565b604051602001610b219190614250565b604051602081830303815290604052610b3e6003610adf8a611a56565b604051602001610b4e91906141ca565b60408051601f1981840301815290829052610b6f9594939291602001613b23565b60405160208183030381529060405290506000610b906004610adf87611a56565b604051602001610ba09190613fa3565b604051602081830303815290604052610bbd6005610adf88611a56565b604051602001610bcd9190614070565b604051602081830303815290604052610bea6006610adf89611a56565b604051602001610bfa9190613ef3565b604051602081830303815290604052610c176007610adf8a611a56565b604051602001610c279190613fff565b604051602081830303815290604052610c446008610adf8b611a56565b604051602001610c5491906140b2565b604051602081830303815290604052610c716009610adf8c611a56565b604051602001610c819190613ccc565b60408051601f1981840301815290829052610ca3969594939291602001613b8e565b6040516020818303038152906040529050828282604051602001610cc993929190613ae0565b6040516020818303038152906040529350505050919050565b610ced335b826122fd565b610d095760405162461bcd60e51b815260040161074d906145bd565b6108838383836123f0565b6000610d1f836112aa565b8210610d815760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161074d565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600a546001600160a01b03610100909104163314610dda5760405162461bcd60e51b815260040161074d90614588565b610de261259b565b565b610883838383604051806020016040528060008152506115bb565b610e0833610ce7565b610e6d5760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b606482015260840161074d565b610e768161262e565b50565b6000610e8460085490565b8210610ee75760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161074d565b60088281548110610efa57610efa6147e1565b90600052602060002001549050919050565b600a546001600160a01b03610100909104163314610f3c5760405162461bcd60e51b815260040161074d90614588565b6040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015610883573d6000803e3d6000fd5b60606000606483610100610f89878960ff166126d5565b610f93919061478b565b610f9d9190614690565b610fa7919061467c565b9050610fb28161271b565b610fbb8261271b565b610fc48361271b565b604051602001610fd6939291906140f4565b6040516020818303038152906040529150505b9392505050565b6040516bffffffffffffffffffffffff193360601b1660208201526000908190603401604051602081830303815290604052805190602001209050611036848483612819565b949350505050565b6000818152600260205260408120546001600160a01b0316806106405760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161074d565b600a546000906001600160a01b036101009091041633146110e85760405162461bcd60e51b815260040161074d90614588565b6040516370a0823160e01b815230600482015282907f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316906370a082319060240160206040518083038186803b15801561114957600080fd5b505afa15801561115d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111819190613951565b10156111c15760405162461bcd60e51b815260206004820152600f60248201526e4e6f7420656e6f756768204c494e4b60881b604482015260640161074d565b610640600f548361282f565b919050565b6040805160208101909152600081526015546060919060ff166111f55792915050565b8061121261120a61120586611a56565b6129ba565b60ff1661271b565b604051602001611223929190613c56565b60408051601f19818403018152919052905060015b600a8160ff1610156112a3578161126e600661125f61125688611a56565b8560ff166126d5565b611269919061478b565b61271b565b60405160200161127f929190613c56565b6040516020818303038152906040529150808061129b9061476b565b915050611238565b5092915050565b60006001600160a01b0382166113155760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161074d565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b036101009091041633146113615760405162461bcd60e51b815260040161074d90614588565b60ff8085166000908152601160205260409020541615158215151461139f5760ff84166000908152601160205260409020805460ff19168315151790555b60ff84811660009081526011602052604090205461010090048116908216146113ec5760ff808516600090815260116020526040902080549183166101000261ff00199092169190911790555b60ff841660009081526011602052604090206001015483146114215760ff841660009081526011602052604090206001018390555b50505050565b600a546001600160a01b036101009091041633146114575760405162461bcd60e51b815260040161074d90614588565b610de260006129fa565b600a546001600160a01b036101009091041633146114915760405162461bcd60e51b815260040161074d90614588565b610de2612a54565b600a546001600160a01b036101009091041633146114c95760405162461bcd60e51b815260040161074d90614588565b80516114dc9060149060208401906134ed565b5050565b600a546001600160a01b036101009091041633146115105760405162461bcd60e51b815260040161074d90614588565b6015805460ff1916911515919091179055565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952161461159b5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c00604482015260640161074d565b60105550565b60606001805461065590614715565b6114dc338383612acf565b6115c533836122fd565b6115e15760405162461bcd60e51b815260040161074d906145bd565b61142184848484612b9e565b60ff8085166000908152601160205260409020541661164e5760405162461bcd60e51b815260206004820152601a60248201527f52656465656d3a2077696e646f77206973206e6f74206f70656e000000000000604482015260640161074d565b60008360ff16116116a15760405162461bcd60e51b815260206004820152601d60248201527f52656465656d3a20616d6f756e742063616e6e6f74206265207a65726f000000604482015260640161074d565b600b8360ff16106117025760405162461bcd60e51b815260206004820152602560248201527f52656465656d3a20616d6f756e742063616e6e6f74206265206d6f72652074686044820152640616e2031360dc1b606482015260840161074d565b6103c38360ff16611712600c5490565b61171c919061463f565b11156117565760405162461bcd60e51b815260206004820152600960248201526813585e081b1a5b5a5d60ba1b604482015260640161074d565b8360ff166003146118755760ff80851660009081526011602090815260408083205433845260129092529091205461010090910482169161179991869116614657565b60ff1611156117ea5760405162461bcd60e51b815260206004820152601b60248201527f546f6f206d616e7920666f722070726573616c652077696e646f770000000000604482015260640161074d565b611839828280806020026020016040519081016040528093929190818152602001838360200280828437600092018290525060ff8a168152601160205260409020600101549250610ff0915050565b6118755760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b604482015260640161074d565b604080516020810190915260008082525b8460ff168160ff1610156118f5576118a6336118a1600c5490565b612bd1565b816118b3611269600c5490565b6040516020016118c4929190613c1b565b60405160208183030381529060405291506118e3600c80546001019055565b806118ed8161476b565b915050611886565b503360009081526012602052604090205461191490859060ff16614657565b3360008181526012602052604090819020805460ff191660ff949094169390931790925590517f0c1b180fbb60448c5491c5ddc7c3a923854214b9ff70f90a7821333338971f9290611967908490614523565b60405180910390a25050505050565b6014805461198390614715565b80601f01602080910402602001604051908101604052809291908181526020018280546119af90614715565b80156119fc5780601f106119d1576101008083540402835291602001916119fc565b820191906000526020600020905b8154815290600101906020018083116119df57829003601f168201915b505050505081565b60606000611a118361271b565b604051602001611a219190614291565b6040516020818303038152906040529050610fe981611a3f856111d2565b611a4886610888565b611a5187611abc565b612beb565b600081611a6260085490565b11611aa15760405162461bcd60e51b815260206004820152600f60248201526e151bdad95b88139bdd08119bdd5b99608a1b604482015260640161074d565b601054611ab057506000919050565b610640601054836126d5565b60155460609060ff16611ae8576040518060600160405280602881526020016148876028913992915050565b611af0613571565b611af8613599565b60015b600a8160ff161015611cb7576000611b1682610adf88611a56565b90508084611b256001856146c6565b60ff1660098110611b3857611b386147e1565b602002015260005b6006811015611ca257600060136000611b5b6112058b611a56565b60ff1660ff1681526020019081526020016000208281548110611b8057611b806147e1565b906000526020600020018054611b9590614715565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc190614715565b8015611c0e5780601f10611be357610100808354040283529160200191611c0e565b820191906000526020600020905b815481529060010190602001808311611bf157829003601f168201915b5050505050905080604051602001611c269190613ac4565b6040516020818303038152906040528051906020012083604051602001611c4d9190613ac4565b604051602081830303815290604052805190602001201415611c8f57848260068110611c7b57611c7b6147e1565b60200201805190611c8b82614750565b9052505b5080611c9a81614750565b915050611b40565b50508080611caf9061476b565b915050611afb565b506000611cc78360006001612c52565b611cd19082614657565b9050611ce08360016002612c52565b611cea9082614657565b9050611cf98360006003612c52565b611d039082614657565b9050611d128360016004612c52565b611d1c9082614657565b9050611d2b8360026005612c52565b611d359082614657565b9050611d448360036004612c52565b611d4e9082614657565b9050611d5d8360046005612c52565b611d679082614657565b9050611d768360036006612c52565b611d809082614657565b9050611d8f8360046007612c52565b611d999082614657565b9050611da88360056008612c52565b611db29082614657565b9050611dc18360066007612c52565b611dcb9082614657565b9050611dda8360076008612c52565b611de49082614657565b90506000805b6006811015611e32576000848260068110611e0757611e076147e1565b60200201511115611e205781611e1c81614750565b9250505b80611e2a81614750565b915050611dea565b50604080518082018252600f81526e2261747472696275746573223a205b60881b602080830191909152825190810190925260008083529091905b6006811015611efc576000611e818261271b565b604051602001611e919190614040565b6040516020818303038152906040529050611ec281888460068110611eb857611eb86147e1565b6020020151612cea565b92508383604051602001611ed7929190613c1b565b6040516020818303038152906040529350508080611ef490614750565b915050611e6d565b50611f2d6040518060400160405280600b81526020016a436f6e6e656374696f6e7360a81b8152508560ff16612cea565b90508181604051602001611f42929190613c1b565b60408051601f19818403018152828201909152600782526650616c6574746560c81b60208301529250611f8390611f7b6112058b611a56565b60ff16612cea565b90508181604051602001611f98929190613c1b565b60408051601f19818403018152828201909152600d82526c546f74616c20436f6c6f75727360981b60208301529250611fd19084612cea565b90508181604051602001611fe6929190613c1b565b60408051601f1981840301815282820190915260118252702130b1b5b3b937bab7321021b7b637bab960791b602083015292506120429061010061203361202c8c611a56565b600a6126d5565b61203d919061478b565b612d1e565b90508181604051602001612057929190613c1b565b60408051601f19818403018152828201909152600c82526b29b434b93a1021b7b637bab960a11b6020830152925061209f906101006120336120988c611a56565b600b6126d5565b905081816040516020016120b4929190613c91565b60408051601f1981840301815291905298975050505050505050565b60606014805461065590614715565b600a546001600160a01b0361010090910416331461210f5760405162461bcd60e51b815260040161074d90614588565b6001600160a01b0381166121745760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161074d565b610e76816129fa565b60006001600160e01b0319821663780e9d6360e01b1480610640575061064082612d3b565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906121d78261103e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b606060006006612223848660ff166126d5565b61222d919061478b565b90506013600061223c856129ba565b60ff1660ff1681526020019081526020016000208181548110612261576122616147e1565b90600052602060002001805461227690614715565b80601f01602080910402602001604051908101604052809291908181526020018280546122a290614715565b80156122ef5780601f106122c4576101008083540402835291602001916122ef565b820191906000526020600020905b8154815290600101906020018083116122d257829003601f168201915b505050505091505092915050565b6000818152600260205260408120546001600160a01b03166123765760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161074d565b60006123818361103e565b9050806001600160a01b0316846001600160a01b031614806123bc5750836001600160a01b03166123b1846106d8565b6001600160a01b0316145b8061103657506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff16611036565b826001600160a01b03166124038261103e565b6001600160a01b03161461246b5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161074d565b6001600160a01b0382166124cd5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161074d565b6124d8838383612d8b565b6124e36000826121a2565b6001600160a01b038316600090815260036020526040812080546001929061250c9084906146af565b90915550506001600160a01b038216600090815260036020526040812080546001929061253a90849061463f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a5460ff166125e45760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161074d565b600a805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60006126398261103e565b905061264781600084612d8b565b6126526000836121a2565b6001600160a01b038116600090815260036020526040812080546001929061267b9084906146af565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000637735940083836040516020016126f8929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c610fe9919061478b565b60608161273f5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612769578061275381614750565b91506127629050600a8361467c565b9150612743565b60008167ffffffffffffffff811115612784576127846147f7565b6040519080825280601f01601f1916602001820160405280156127ae576020820181803683370190505b5090505b8415611036576127c36001836146af565b91506127d0600a8661478b565b6127db90603061463f565b60f81b8183815181106127f0576127f06147e1565b60200101906001600160f81b031916908160001a905350612812600a8661467c565b94506127b2565b6000826128268584612d96565b14949350505050565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb79528486600060405160200161289f929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016128cc939291906144f3565b602060405180830381600087803b1580156128e657600080fd5b505af11580156128fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061291e9190613876565b506000838152600b6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a09091019092528151918301919091209387905291905261297a90600161463f565b6000858152600b60205260409020556110368482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600060066129c9600a8461478b565b10156129d757506000919050565b60096129e4600a8461478b565b10156129f257506001919050565b506002919050565b600a80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a5460ff1615612a9a5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161074d565b600a805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586126113390565b816001600160a01b0316836001600160a01b03161415612b315760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161074d565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612ba98484846123f0565b612bb584848484612e42565b6114215760405162461bcd60e51b815260040161074d90614536565b6114dc828260405180602001604052806000815250612f4c565b606060008585612bfa86612f7f565b85604051602001612c0e9493929190613e11565b6040516020818303038152906040529050612c2881612f7f565b604051602001612c38919061420b565b604051602081830303815290604052915050949350505050565b6000838260ff1660098110612c6957612c696147e1565b6020020151604051602001612c7e9190613ac4565b60405160208183030381529060405280519060200120848460ff1660098110612ca957612ca96147e1565b6020020151604051602001612cbe9190613ac4565b604051602081830303815290604052805190602001201415612ce257506001610fe9565b506000610fe9565b606082612cf68361271b565b604051602001612d07929190613d29565b604051602081830303815290604052905092915050565b606082612d2a8361271b565b604051602001612d07929190613d9e565b60006001600160e01b031982166380ac58cd60e01b1480612d6c57506001600160e01b03198216635b5e139f60e01b145b8061064057506301ffc9a760e01b6001600160e01b0319831614610640565b6108838383836130e5565b600081815b8451811015612e3a576000858281518110612db857612db86147e1565b60200260200101519050808311612dfa576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250612e27565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b5080612e3281614750565b915050612d9b565b509392505050565b60006001600160a01b0384163b15612f4457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612e869033908990889088906004016144b6565b602060405180830381600087803b158015612ea057600080fd5b505af1925050508015612ed0575060408051601f3d908101601f19168201909252612ecd918101906138d2565b60015b612f2a573d808015612efe576040519150601f19603f3d011682016040523d82523d6000602084013e612f03565b606091505b508051612f225760405162461bcd60e51b815260040161074d90614536565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611036565b506001611036565b612f568383613157565b612f636000848484612e42565b6108835760405162461bcd60e51b815260040161074d90614536565b805160609080612f9f575050604080516020810190915260008152919050565b60006003612fae83600261463f565b612fb8919061467c565b612fc3906004614690565b90506000612fd282602061463f565b67ffffffffffffffff811115612fea57612fea6147f7565b6040519080825280601f01601f191660200182016040528015613014576020820181803683370190505b5090506000604051806060016040528060408152602001614847604091399050600181016020830160005b868110156130a0576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b83526004909201910161303f565b5060038606600181146130ba57600281146130cb576130d7565b613d3d60f01b6001198301526130d7565b603d60f81b6000198301525b505050918152949350505050565b6130f08383836132a5565b600a5460ff16156108835760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201526a1a1a5b19481c185d5cd95960aa1b606482015260840161074d565b6001600160a01b0382166131ad5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161074d565b6000818152600260205260409020546001600160a01b0316156132125760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161074d565b61321e60008383612d8b565b6001600160a01b038216600090815260036020526040812080546001929061324790849061463f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b038316613300576132fb81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613323565b816001600160a01b0316836001600160a01b03161461332357613323838261335d565b6001600160a01b03821661333a57610883816133fa565b826001600160a01b0316826001600160a01b0316146108835761088382826134a9565b6000600161336a846112aa565b61337491906146af565b6000838152600760205260409020549091508082146133c7576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061340c906001906146af565b60008381526009602052604081205460088054939450909284908110613434576134346147e1565b906000526020600020015490508060088381548110613455576134556147e1565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061348d5761348d6147cb565b6001900381819060005260206000200160009055905550505050565b60006134b4836112aa565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b8280546134f990614715565b90600052602060002090601f01602090048101928261351b5760008555613561565b82601f1061353457805160ff1916838001178555613561565b82800160010185558215613561579182015b82811115613561578251825591602001919060010190613546565b5061356d9291506135b7565b5090565b6040518061012001604052806009905b60608152602001906001900390816135815790505090565b6040518060c001604052806006906020820280368337509192915050565b5b8082111561356d57600081556001016135b8565b600067ffffffffffffffff8311156135e6576135e66147f7565b6135f9601f8401601f191660200161460e565b905082815283838301111561360d57600080fd5b828260208301376000602084830101529392505050565b803560ff811681146111cd57600080fd5b60006020828403121561364757600080fd5b8135610fe98161480d565b6000806040838503121561366557600080fd5b82356136708161480d565b946020939093013593505050565b6000806040838503121561369157600080fd5b823561369c8161480d565b915060208301356136ac8161480d565b809150509250929050565b6000806000606084860312156136cc57600080fd5b83356136d78161480d565b925060208401356136e78161480d565b929592945050506040919091013590565b6000806000806080858703121561370e57600080fd5b84356137198161480d565b935060208501356137298161480d565b925060408501359150606085013567ffffffffffffffff81111561374c57600080fd5b8501601f8101871361375d57600080fd5b61376c878235602084016135cc565b91505092959194509250565b6000806040838503121561378b57600080fd5b82356137968161480d565b915060208301356136ac81614822565b600080604083850312156137b957600080fd5b823567ffffffffffffffff808211156137d157600080fd5b818501915085601f8301126137e557600080fd5b81356020828211156137f9576137f96147f7565b8160051b925061380a81840161460e565b8281528181019085830185870184018b101561382557600080fd5b600096505b8487101561384857803583526001969096019591830191830161382a565b509997909101359750505050505050565b60006020828403121561386b57600080fd5b8135610fe981614822565b60006020828403121561388857600080fd5b8151610fe981614822565b600080604083850312156138a657600080fd5b50508035926020909101359150565b6000602082840312156138c757600080fd5b8135610fe981614830565b6000602082840312156138e457600080fd5b8151610fe981614830565b60006020828403121561390157600080fd5b813567ffffffffffffffff81111561391857600080fd5b8201601f8101841361392957600080fd5b611036848235602084016135cc565b60006020828403121561394a57600080fd5b5035919050565b60006020828403121561396357600080fd5b5051919050565b60006020828403121561397c57600080fd5b610fe982613624565b6000806000806080858703121561399b57600080fd5b6139a485613624565b93506020850135925060408501356139bb81614822565b91506139c960608601613624565b905092959194509250565b6000806000606084860312156139e957600080fd5b6139f284613624565b95602085013595506040909401359392505050565b60008060008060608587031215613a1d57600080fd5b613a2685613624565b9350613a3460208601613624565b9250604085013567ffffffffffffffff80821115613a5157600080fd5b818701915087601f830112613a6557600080fd5b813581811115613a7457600080fd5b8860208260051b8501011115613a8957600080fd5b95989497505060200194505050565b60008151808452613ab08160208601602086016146e9565b601f01601f19169290920160200192915050565b60008251613ad68184602087016146e9565b9190910192915050565b60008451613af28184602089016146e9565b845190830190613b068183602089016146e9565b8451910190613b198183602088016146e9565b0195945050505050565b60008651613b35818460208b016146e9565b865190830190613b49818360208b016146e9565b8651910190613b5c818360208a016146e9565b8551910190613b6f8183602089016146e9565b8451910190613b828183602088016146e9565b01979650505050505050565b600087516020613ba18285838d016146e9565b885191840191613bb48184848d016146e9565b8851920191613bc68184848c016146e9565b8751920191613bd88184848b016146e9565b8651920191613bea8184848a016146e9565b8551920191613bfc81848489016146e9565b651e17b9bb339f60d11b92019182525060060198975050505050505050565b60008351613c2d8184602088016146e9565b835190830190613c418183602088016146e9565b600b60fa1b9101908152600101949350505050565b60008351613c688184602088016146e9565b835190830190613c7c8183602088016146e9565b600160fd1b9101908152600101949350505050565b60008351613ca38184602088016146e9565b835190830190613cb78183602088016146e9565b605d60f81b9101908152600101949350505050565b6000805160206148af833981519152815272191b1811103c9e91191b1811103334b6361e9160691b602082015260008251613d0e8160338501602087016146e9565b631110179f60e11b6033939091019283015250603701919050565b6f3d913a3930b4ba2fba3cb832911d101160811b81528251600090613d558160108501602088016146e9565b6d11101610113b30b63ab2911d101160911b6010918401918201528351613d8381601e8401602088016146e9565b61227d60f01b601e9290910191820152602001949350505050565b6f3d913a3930b4ba2fba3cb832911d101160811b81528251600090613dca8160108501602088016146e9565b6c011101610113b30b63ab2911d1609d1b6010918401918201528351613df781601d8401602088016146e9565b607d60f81b601d9290910191820152601e01949350505050565b683d913730b6b2911d1160b91b81528451600090613e36816009850160208a016146e9565b701116113232b9b1b934b83a34b7b7111d1160791b6009918401918201528551613e6781601a840160208a016146e9565b7f222c22696d616765223a2022646174613a696d6167652f7376672b786d6c3b62601a929091019182015265185cd94d8d0b60d21b603a8201528451613eb48160408401602089016146e9565b61088b60f21b604092909101918201528351613ed78160428401602088016146e9565b607d60f81b604292909101918201526043019695505050505050565b6000805160206148af833981519152815272191b1811103c9e91189b9811103334b6361e9160691b602082015260008251613d0e8160338501602087016146e9565b7f3c726563742077696474683d2231323022206865696768743d2237302220783d815272223135302220793d22333530222066696c6c3d60681b602082015260008251613f898160338501602087016146e9565b6210179f60e91b6033939091019283015250603601919050565b6000805160206148af8339815191528152711c1811103c9e91189b9811103334b6361e9160711b602082015260008251613fe48160328501602087016146e9565b631110179f60e11b6032939091019283015250603601919050565b6000805160206148af8339815191528152711c1811103c9e91191b1811103334b6361e9160711b602082015260008251613fe48160328501602087016146e9565b67436f6c6f7572202360c01b8152600082516140638160088501602087016146e9565b9190910160080192915050565b6000805160206148af833981519152815272189b9811103c9e91189b9811103334b6361e9160691b602082015260008251613d0e8160338501602087016146e9565b6000805160206148af833981519152815272189b9811103c9e91191b1811103334b6361e9160691b602082015260008251613d0e8160338501602087016146e9565b64044e4cec4560db1b815283516000906141158160058501602089016146e9565b8083019050600b60fa1b8060058301528551614138816006850160208a016146e9565b600692019182015283516141538160078401602088016146e9565b61149160f11b6007929091019182015260090195945050505050565b6000805160206148af8339815191528152701c1811103c9e911c1811103334b6361e9160791b6020820152600082516141af8160318501602087016146e9565b631110179f60e11b6031939091019283015250603501919050565b6000805160206148af833981519152815271191b1811103c9e911c1811103334b6361e9160711b602082015260008251613fe48160328501602087016146e9565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161424381601d8501602087016146e9565b91909101601d0192915050565b6000805160206148af833981519152815271189b9811103c9e911c1811103334b6361e9160711b602082015260008251613fe48160328501602087016146e9565b69536372616d626c65202360b01b8152600082516142b681600a8501602087016146e9565b91909101600a0192915050565b7f3c726563742077696474683d2232383022206865696768743d223238302220788152713d2238302220793d223830222066696c6c3d60701b6020820152600082516143168160328501602087016146e9565b6210179f60e91b6032939091019283015250603501919050565b7f3c726563742077696474683d2232383022206865696768743d223238302220788152713d2239302220793d223930222066696c6c3d60701b6020820152600082516143168160328501602087016146e9565b7f3c726563742077696474683d2234323022206865696768743d2234323022207881526f3d22302220793d2230222066696c6c3d60801b6020820152600082516143d48160308501602087016146e9565b6210179f60e91b6030939091019283015250603301919050565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f32308152600060207f30302f737667222077696474683d2234323022206865696768743d223432302281840152601f60f91b60408401526041885161445781838701858d016146e9565b88519085019061446c81848401868d016146e9565b885191019061448081848401868c016146e9565b875191019061449481848401868b016146e9565b86519101906144a881848401868a016146e9565b010198975050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906144e990830184613a98565b9695505050505050565b60018060a01b038416815282602082015260606040820152600061451a6060830184613a98565b95945050505050565b602081526000610fe96020830184613a98565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff81118282101715614637576146376147f7565b604052919050565b600082198211156146525761465261479f565b500190565b600060ff821660ff84168060ff038211156146745761467461479f565b019392505050565b60008261468b5761468b6147b5565b500490565b60008160001904831182151516156146aa576146aa61479f565b500290565b6000828210156146c1576146c161479f565b500390565b600060ff821660ff8416808210156146e0576146e061479f565b90039392505050565b60005b838110156147045781810151838201526020016146ec565b838111156114215750506000910152565b600181811c9082168061472957607f821691505b6020821081141561474a57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156147645761476461479f565b5060010190565b600060ff821660ff8114156147825761478261479f565b60010192915050565b60008261479a5761479a6147b5565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610e7657600080fd5b8015158114610e7657600080fd5b6001600160e01b031981168114610e7657600080fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f2261747472696275746573223a205b7b2276616c7565223a2022556e736372616d626c6564227d5d3c726563742077696474683d22383022206865696768743d2238302220783d22a2646970667358221220183c932e9248e9bc2474e40669e0d603165095cbea4b6cbfa8ac3c65a8ca66ed64736f6c63430008070033

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

000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986caaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af4450000000000000000000000000000000000000000000000000000000000000009536372616d626c6573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045343524d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000041f707fa87cca6d5e52f76e8fbf0ecb9130818402856cf57b32be54af249473469c7ac34dd9c8380d4dc0bed49bdb8fbba354a19a9088370869ea90513e6d192c485a5f2f27d6d6755110bd308edda7118fbcba62507b7758617256f8a535de7b1e0fa23b9aeab82ec0dd34d09000e75c6fd16dccda9c8d2694ecd4f190213f45000000000000000000000000000000000000000000000000000000000000005068747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066732f516d58714c754a72786b78616d617373525157434e5641625a474e685253777338424d6d32794a397339354b414400000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): Scrambles
Arg [1] : _symbol (string): SCRM
Arg [2] : _maxRedeemPerWallet (uint8[]): 3,2,1,100
Arg [3] : _merkleRoots (bytes32[]): System.Byte[],System.Byte[],System.Byte[],System.Byte[]
Arg [4] : _contractMetaDataURI (string): https://gateway.pinata.cloud/ipfs/QmXqLuJrxkxamassRQWCNVAbZGNhRSws8BMm2yJ9s95KAD
Arg [5] : _VRFCoordinator (address): 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952
Arg [6] : _LinkToken (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [7] : _keyHash (bytes32): 0xaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445

-----Encoded View---------------
26 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000220
Arg [4] : 00000000000000000000000000000000000000000000000000000000000002c0
Arg [5] : 000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952
Arg [6] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [7] : aa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [9] : 536372616d626c65730000000000000000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [11] : 5343524d00000000000000000000000000000000000000000000000000000000
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [18] : 1f707fa87cca6d5e52f76e8fbf0ecb9130818402856cf57b32be54af24947346
Arg [19] : 9c7ac34dd9c8380d4dc0bed49bdb8fbba354a19a9088370869ea90513e6d192c
Arg [20] : 485a5f2f27d6d6755110bd308edda7118fbcba62507b7758617256f8a535de7b
Arg [21] : 1e0fa23b9aeab82ec0dd34d09000e75c6fd16dccda9c8d2694ecd4f190213f45
Arg [22] : 0000000000000000000000000000000000000000000000000000000000000050
Arg [23] : 68747470733a2f2f676174657761792e70696e6174612e636c6f75642f697066
Arg [24] : 732f516d58714c754a72786b78616d617373525157434e5641625a474e685253
Arg [25] : 777338424d6d32794a397339354b414400000000000000000000000000000000


Deployed Bytecode Sourcemap

75737:18652:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83050:188;;;;;;:::i;:::-;;:::i;:::-;;;34498:14:1;;34491:22;34473:41;;34461:2;34446:18;83050:188:0;;;;;;;;54963:100;;;:::i;:::-;;;;;;;:::i;56522:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;33406:32:1;;;33388:51;;33376:2;33361:18;56522:221:0;33242:203:1;56045:411:0;;;;;;:::i;:::-;;:::i;:::-;;89289:2472;;;;;;:::i;:::-;;:::i;76423:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;48070:4:1;48058:17;;;48040:36;;48028:2;48013:18;76423:44:0;47898:184:1;68109:113:0;68197:10;:17;68109:113;;;35012:25:1;;;35000:2;34985:18;68109:113:0;34866:177:1;57272:339:0;;;;;;:::i;:::-;;:::i;67777:256::-;;;;;;:::i;:::-;;:::i;76101:29::-;;;;;-1:-1:-1;;;;;76101:29:0;;;79217:76;;;:::i;57682:185::-;;;;;;:::i;:::-;;:::i;74153:245::-;;;;;;:::i;:::-;;:::i;68299:233::-;;;;;;:::i;:::-;;:::i;76137:24::-;;;;;-1:-1:-1;;;;;76137:24:0;;;76566:20;;;;;;;;;80588:123;;;;;;:::i;:::-;;:::i;92443:312::-;;;;;;:::i;:::-;;:::i;30573:86::-;30644:7;;;;30573:86;;76357:59;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34742:14:1;;34735:22;34717:41;;34806:4;34794:17;;;34789:2;34774:18;;34767:45;34828:18;;;34821:34;34705:2;34690:18;76357:59:0;34525:336:1;82448:225:0;;;;;;:::i;:::-;;:::i;54657:239::-;;;;;;:::i;:::-;;:::i;93315:208::-;;;;;;:::i;:::-;;:::i;84342:549::-;;;;;;:::i;:::-;;:::i;54387:208::-;;;;;;:::i;:::-;;:::i;79765:651::-;;;;;;:::i;:::-;;:::i;33472:103::-;;;:::i;79031:72::-;;;:::i;32821:87::-;32894:6;;;;;-1:-1:-1;;;;;32894:6:0;32821:87;;83464:98;;;;;;:::i;:::-;;:::i;79356:82::-;;;;;;:::i;:::-;;:::i;15524:233::-;;;;;;:::i;:::-;;:::i;55132:104::-;;;:::i;76199:23::-;;;;;;56815:155;;;;;;:::i;:::-;;:::i;57938:328::-;;;;;;:::i;:::-;;:::i;81010:1264::-;;;;;;:::i;:::-;;:::i;76531:26::-;;;:::i;83828:292::-;;;;;;:::i;:::-;;:::i;93694:281::-;;;;;;:::i;:::-;;:::i;85589:2721::-;;;;;;:::i;:::-;;:::i;83570:97::-;;;:::i;57041:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;57162:25:0;;;57138:4;57162:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;57041:164;76039:35;;76071:3;76039:35;;33730:201;;;;;;:::i;:::-;;:::i;83050:188::-;83170:4;83194:36;83218:11;83194:23;:36::i;:::-;83187:43;83050:188;-1:-1:-1;;83050:188:0:o;54963:100::-;55017:13;55050:5;55043:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54963:100;:::o;56522:221::-;56598:7;59865:16;;;:7;:16;;;;;;-1:-1:-1;;;;;59865:16:0;56618:73;;;;-1:-1:-1;;;56618:73:0;;43771:2:1;56618:73:0;;;43753:21:1;43810:2;43790:18;;;43783:30;43849:34;43829:18;;;43822:62;-1:-1:-1;;;43900:18:1;;;43893:42;43952:19;;56618:73:0;;;;;;;;;-1:-1:-1;56711:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;56711:24:0;;56522:221::o;56045:411::-;56126:13;56142:23;56157:7;56142:14;:23::i;:::-;56126:39;;56190:5;-1:-1:-1;;;;;56184:11:0;:2;-1:-1:-1;;;;;56184:11:0;;;56176:57;;;;-1:-1:-1;;;56176:57:0;;45315:2:1;56176:57:0;;;45297:21:1;45354:2;45334:18;;;45327:30;45393:34;45373:18;;;45366:62;-1:-1:-1;;;45444:18:1;;;45437:31;45485:19;;56176:57:0;45113:397:1;56176:57:0;29307:10;-1:-1:-1;;;;;56268:21:0;;;;:62;;-1:-1:-1;56293:37:0;56310:5;29307:10;57041:164;:::i;56293:37::-;56246:168;;;;-1:-1:-1;;;56246:168:0;;41820:2:1;56246:168:0;;;41802:21:1;41859:2;41839:18;;;41832:30;41898:34;41878:18;;;41871:62;41969:26;41949:18;;;41942:54;42013:19;;56246:168:0;41618:420:1;56246:168:0;56427:21;56436:2;56440:7;56427:8;:21::i;:::-;56115:341;56045:411;;:::o;89289:2472::-;89387:8;;89349:13;;89387:8;;89383:49;;-1:-1:-1;;89411:9:0;;;;;;;;;-1:-1:-1;89411:9:0;;;89289:2472::o;89383:49::-;89444:24;89648:32;89656:2;89659:16;89667:7;89659;:16::i;:::-;89676:3;89648:7;:32::i;:::-;89580:107;;;;;;;;:::i;:::-;;;;;;;;;;;;;89776:31;89784:2;89787:16;89795:7;89787;:16::i;:::-;89804:2;89776:7;:31::i;:::-;89706:108;;;;;;;;:::i;:::-;;;;;;;;;;;;;89903:31;89911:2;89914:16;89922:7;89914;:16::i;:::-;89931:2;89903:7;:31::i;:::-;89833:108;;;;;;;;:::i;:::-;;;;;;;;;;;;;89960:82;;;;;;27409:66:1;27397:79;;27506:66;27501:2;27492:12;;27485:88;27598:2;27589:12;;27195:412;89960:82:0;;;;;;;;;;;;;90132:32;90140:2;90143:16;90151:7;90143;:16::i;90132:32::-;90061:110;;;;;;;;:::i;:::-;;;;-1:-1:-1;;90061:110:0;;;;;;;;;;89478:695;;;;;;90061:110;89478:695;;:::i;:::-;;;;;;;;;;;;;89444:730;;90187:24;90263:82;;;;;;27826:66:1;27814:79;;27923:66;27918:2;27909:12;;27902:88;28015:2;28006:12;;27612:412;90263:82:0;;;;;;;;;;;;;90364;;;;;;19396:66:1;19384:79;;19493:66;19488:2;19479:12;;19472:88;19585:2;19576:12;;19182:412;90364:82:0;;;;;;;;;;;;;90534:29;90544:1;90546:16;90554:7;90546;:16::i;:::-;90534:9;:29::i;:::-;90465:106;;;;;;;;:::i;:::-;;;;;;;;;;;;;90660:29;90670:1;90672:16;90680:7;90672;:16::i;90660:29::-;90590:107;;;;;;;;:::i;:::-;;;;;;;;;;;;;90786:29;90796:1;90798:16;90806:7;90798;:16::i;90786:29::-;90716:107;;;;;;;;:::i;:::-;;;;-1:-1:-1;;90716:107:0;;;;;;;;;;90221:604;;;;;;90716:107;90221:604;;:::i;:::-;;;;;;;;;;;;;90187:639;;90839:26;90980:29;90990:1;90992:16;91000:7;90992;:16::i;90980:29::-;90910:107;;;;;;;;:::i;:::-;;;;;;;;;;;;;91107:29;91117:1;91119:16;91127:7;91119;:16::i;91107:29::-;91036:108;;;;;;;;:::i;:::-;;;;;;;;;;;;;91234:29;91244:1;91246:16;91254:7;91246;:16::i;91234:29::-;91163:108;;;;;;;;:::i;:::-;;;;;;;;;;;;;91360:29;91370:1;91372:16;91380:7;91372;:16::i;91360:29::-;91290:107;;;;;;;;:::i;:::-;;;;;;;;;;;;;91487:29;91497:1;91499:16;91507:7;91499;:16::i;91487:29::-;91416:108;;;;;;;;:::i;:::-;;;;;;;;;;;;;91614:29;91624:1;91626:16;91634:7;91626;:16::i;91614:29::-;91543:108;;;;;;;;:::i;:::-;;;;-1:-1:-1;;91543:108:0;;;;;;;;;;90875:797;;;;;;;91543:108;90875:797;;:::i;:::-;;;;;;;;;;;;;90839:834;;91717:10;91728;91739:12;91700:52;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;91686:67;;;;;89289:2472;;;:::o;57272:339::-;57467:41;29307:10;57486:12;57500:7;57467:18;:41::i;:::-;57459:103;;;;-1:-1:-1;;;57459:103:0;;;;;;;:::i;:::-;57575:28;57585:4;57591:2;57595:7;57575:9;:28::i;67777:256::-;67874:7;67910:23;67927:5;67910:16;:23::i;:::-;67902:5;:31;67894:87;;;;-1:-1:-1;;;67894:87:0;;36910:2:1;67894:87:0;;;36892:21:1;36949:2;36929:18;;;36922:30;36988:34;36968:18;;;36961:62;-1:-1:-1;;;37039:18:1;;;37032:41;37090:19;;67894:87:0;36708:407:1;67894:87:0;-1:-1:-1;;;;;;67999:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;67777:256::o;79217:76::-;32894:6;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;79275:10:::1;:8;:10::i;:::-;79217:76::o:0;57682:185::-;57820:39;57837:4;57843:2;57847:7;57820:39;;;;;;;;;;;;:16;:39::i;74153:245::-;74271:41;29307:10;74290:12;29227:98;74271:41;74263:102;;;;-1:-1:-1;;;74263:102:0;;47248:2:1;74263:102:0;;;47230:21:1;47287:2;47267:18;;;47260:30;47326:34;47306:18;;;47299:62;-1:-1:-1;;;47377:18:1;;;47370:46;47433:19;;74263:102:0;47046:412:1;74263:102:0;74376:14;74382:7;74376:5;:14::i;:::-;74153:245;:::o;68299:233::-;68374:7;68410:30;68197:10;:17;;68109:113;68410:30;68402:5;:38;68394:95;;;;-1:-1:-1;;;68394:95:0;;46493:2:1;68394:95:0;;;46475:21:1;46532:2;46512:18;;;46505:30;46571:34;46551:18;;;46544:62;-1:-1:-1;;;46622:18:1;;;46615:42;46674:19;;68394:95:0;46291:408:1;68394:95:0;68507:10;68518:5;68507:17;;;;;;;;:::i;:::-;;;;;;;;;68500:24;;68299:233;;;:::o;80588:123::-;32894:6;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;80682:21:::1;::::0;-1:-1:-1;;;;;80682:12:0;::::1;::::0;:21;::::1;;;::::0;80695:7;;80682:21:::1;::::0;;;80695:7;80682:12;:21;::::1;;;;;;;;;;;;;::::0;::::1;;;;92443:312:::0;92534:13;92565:12;92632:3;92620:10;92615:3;92582:30;92595:4;92600:11;92582:30;;:12;:30::i;:::-;:36;;;;:::i;:::-;92581:49;;;;:::i;:::-;92580:55;;;;:::i;:::-;92565:70;;92685:15;:4;:13;:15::i;:::-;92705;:4;:13;:15::i;:::-;92725;:4;:13;:15::i;:::-;92660:86;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;92646:101;;;92443:312;;;;;;:::o;82448:225::-;82581:28;;-1:-1:-1;;82598:10:0;8776:2:1;8772:15;8768:53;82581:28:0;;;8756:66:1;82534:4:0;;;;8838:12:1;;82581:28:0;;;;;;;;;;;;82571:39;;;;;;82556:54;;82628:37;82647:5;82654:4;82660;82628:18;:37::i;:::-;82621:44;82448:225;-1:-1:-1;;;;82448:225:0:o;54657:239::-;54729:7;54765:16;;;:7;:16;;;;;;-1:-1:-1;;;;;54765:16:0;54800:19;54792:73;;;;-1:-1:-1;;;54792:73:0;;42656:2:1;54792:73:0;;;42638:21:1;42695:2;42675:18;;;42668:30;42734:34;42714:18;;;42707:62;-1:-1:-1;;;42785:18:1;;;42778:39;42834:19;;54792:73:0;42454:405:1;93315:208:0;32894:6;;93372:17;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;93410:29:::1;::::0;-1:-1:-1;;;93410:29:0;;93433:4:::1;93410:29;::::0;::::1;33388:51:1::0;93443:3:0;;93410:4:::1;-1:-1:-1::0;;;;;93410:14:0::1;::::0;::::1;::::0;33361:18:1;;93410:29:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:36;;93402:64;;;::::0;-1:-1:-1;;;93402:64:0;;41476:2:1;93402:64:0::1;::::0;::::1;41458:21:1::0;41515:2;41495:18;;;41488:30;-1:-1:-1;;;41534:18:1;;;41527:45;41589:18;;93402:64:0::1;41274:339:1::0;93402:64:0::1;93484:31;93502:7;;93511:3;93484:17;:31::i;33112:1::-;93315:208:::0;;;:::o;84342:549::-;84446:30;;;;;;;;;:25;:30;;84493:8;;84421:13;;84446:30;84493:8;;84489:68;;84534:11;84342:549;-1:-1:-1;;84342:549:0:o;84489:68::-;84607:11;84619:44;:33;84635:16;84643:7;84635;:16::i;:::-;84619:15;:33::i;:::-;:42;;;:44::i;:::-;84590:78;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;84590:78:0;;;;;;;;;;-1:-1:-1;84696:1:0;84682:171;84703:2;84699:1;:6;;;84682:171;;;84774:11;84786:49;84822:1;84787:32;84800:16;84808:7;84800;:16::i;:::-;84817:1;84787:32;;:12;:32::i;:::-;:36;;;;:::i;:::-;84786:47;:49::i;:::-;84757:83;;;;;;;;;:::i;:::-;;;;;;;;;;;;;84736:105;;84707:3;;;;;:::i;:::-;;;;84682:171;;;-1:-1:-1;84872:11:0;84342:549;-1:-1:-1;;84342:549:0:o;54387:208::-;54459:7;-1:-1:-1;;;;;54487:19:0;;54479:74;;;;-1:-1:-1;;;54479:74:0;;42245:2:1;54479:74:0;;;42227:21:1;42284:2;42264:18;;;42257:30;42323:34;42303:18;;;42296:62;-1:-1:-1;;;42374:18:1;;;42367:40;42424:19;;54479:74:0;42043:406:1;54479:74:0;-1:-1:-1;;;;;;54571:16:0;;;;;:9;:16;;;;;;;54387:208::o;79765:651::-;32894:6;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;79952:28:::1;::::0;;::::1;;::::0;;;:17:::1;:28;::::0;;;;:33;::::1;:42;;::::0;::::1;;;79949:124;;80020:28;::::0;::::1;;::::0;;;:17:::1;:28;::::0;;;;:41;;-1:-1:-1;;80020:41:0::1;::::0;::::1;;;::::0;;79949:124:::1;80086:64;:28:::0;;::::1;;::::0;;;:17:::1;:28;::::0;;;;:47;::::1;::::0;::::1;::::0;::::1;:64:::0;;::::1;;80083:168;;80176:28;::::0;;::::1;;::::0;;;:17:::1;:28;::::0;;;;:63;;;;::::1;;;-1:-1:-1::0;;80176:63:0;;::::1;::::0;;;::::1;::::0;;80083:168:::1;80264:28;::::0;::::1;;::::0;;;:17:::1;:28;::::0;;;;:39:::1;;::::0;:54;::::1;80261:148;;80344:28;::::0;::::1;;::::0;;;:17:::1;:28;::::0;;;;:39:::1;;:53:::0;;;80261:148:::1;79765:651:::0;;;;:::o;33472:103::-;32894:6;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;33537:30:::1;33564:1;33537:18;:30::i;79031:72::-:0;32894:6;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;79087:8:::1;:6;:8::i;83464:98::-:0;32894:6;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;83536:18;;::::1;::::0;:12:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;:::-;;83464:98:::0;:::o;79356:82::-;32894:6;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;79414:8:::1;:16:::0;;-1:-1:-1;;79414:16:0::1;::::0;::::1;;::::0;;;::::1;::::0;;79356:82::o;15524:233::-;15640:10;-1:-1:-1;;;;;15654:14:0;15640:28;;15632:72;;;;-1:-1:-1;;;15632:72:0;;44955:2:1;15632:72:0;;;44937:21:1;44994:2;44974:18;;;44967:30;45033:33;45013:18;;;45006:61;45084:18;;15632:72:0;44753:355:1;15632:72:0;83013:8;:21;-1:-1:-1;83464:98:0:o;55132:104::-;55188:13;55221:7;55214:14;;;;;:::i;56815:155::-;56910:52;29307:10;56943:8;56953;56910:18;:52::i;57938:328::-;58113:41;29307:10;58146:7;58113:18;:41::i;:::-;58105:103;;;;-1:-1:-1;;;58105:103:0;;;;;;;:::i;:::-;58219:39;58233:4;58239:2;58243:7;58252:5;58219:13;:39::i;81010:1264::-;81144:30;;;;;;;;:17;:30;;;;;:35;;81136:74;;;;-1:-1:-1;;;81136:74:0;;39670:2:1;81136:74:0;;;39652:21:1;39709:2;39689:18;;;39682:30;39748:28;39728:18;;;39721:56;39794:18;;81136:74:0;39468:350:1;81136:74:0;81238:1;81229:6;:10;;;81221:52;;;;-1:-1:-1;;;81221:52:0;;45717:2:1;81221:52:0;;;45699:21:1;45756:2;45736:18;;;45729:30;45795:31;45775:18;;;45768:59;45844:18;;81221:52:0;45515:353:1;81221:52:0;81301:2;81292:6;:11;;;81284:61;;;;-1:-1:-1;;;81284:61:0;;38148:2:1;81284:61:0;;;38130:21:1;38187:2;38167:18;;;38160:30;38226:34;38206:18;;;38199:62;-1:-1:-1;;;38277:18:1;;;38270:35;38322:19;;81284:61:0;37946:401:1;81284:61:0;76071:3;81391:6;81364:33;;:24;:14;25923;;25831:114;81364:24;:33;;;;:::i;:::-;:45;;81356:67;;;;-1:-1:-1;;;81356:67:0;;40025:2:1;81356:67:0;;;40007:21:1;40064:1;40044:18;;;40037:29;-1:-1:-1;;;40082:18:1;;;40075:39;40131:18;;81356:67:0;39823:332:1;81356:67:0;81439:11;:16;;81454:1;81439:16;81436:423;;81602:30;;;;;;;;:17;:30;;;;;;;;:49;81577:10;81565:23;;:11;:23;;;;;;;81602:49;;;;;;;81565:32;;81591:6;;81565:23;:32;:::i;:::-;:86;;;;81557:126;;;;-1:-1:-1;;;81557:126:0;;40775:2:1;81557:126:0;;;40757:21:1;40814:2;40794:18;;;40787:30;40853:29;40833:18;;;40826:57;40900:18;;81557:126:0;40573:351:1;81557:126:0;81747:73;81765:11;;81747:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81778:30:0;;;;;:17;:30;;;;;:41;;;;-1:-1:-1;81747:17:0;;-1:-1:-1;;81747:73:0:i;:::-;81739:98;;;;-1:-1:-1;;;81739:98:0;;46906:2:1;81739:98:0;;;46888:21:1;46945:2;46925:18;;;46918:30;-1:-1:-1;;;46964:18:1;;;46957:43;47017:18;;81739:98:0;46704:337:1;81739:98:0;81871:25;;;;;;;;;:20;:25;;;81909:247;81930:6;81926:10;;:1;:10;;;81909:247;;;81958:47;81968:10;81980:24;:14;25923;;25831:114;81980:24;81958:9;:47::i;:::-;82053:6;82061:35;:24;:14;25923;;25831:114;82061:35;82036:66;;;;;;;;;:::i;:::-;;;;;;;;;;;;;82020:83;;82118:26;:14;26042:19;;26060:1;26042:19;;;25953:127;82118:26;81938:3;;;;:::i;:::-;;;;81909:247;;;-1:-1:-1;82204:10:0;82192:23;;;;:11;:23;;;;;;:32;;82218:6;;82192:23;;:32;:::i;:::-;82178:10;82166:23;;;;:11;:23;;;;;;;:58;;-1:-1:-1;;82166:58:0;;;;;;;;;;;;;82240:26;;;;;;82259:6;;82240:26;:::i;:::-;;;;;;;;81106:1168;81010:1264;;;;:::o;76531:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;83828:292::-;83901:13;83927:18;83986;:7;:16;:18::i;:::-;83955:50;;;;;;;;:::i;:::-;;;;;;;;;;;;;83927:79;;84024:88;84040:4;84046:23;84061:7;84046:14;:23::i;:::-;84071:21;84084:7;84071:12;:21::i;:::-;84093:18;84103:7;84093:9;:18::i;:::-;84024:15;:88::i;93694:281::-;93749:7;93796;93782:13;68197:10;:17;;68109:113;93782:13;:21;93774:49;;;;-1:-1:-1;;;93774:49:0;;43066:2:1;93774:49:0;;;43048:21:1;43105:2;43085:18;;;43078:30;-1:-1:-1;;;43124:18:1;;;43117:45;43179:18;;93774:49:0;42864:339:1;93774:49:0;93840:8;;93836:132;;-1:-1:-1;93876:1:0;;93694:281;-1:-1:-1;93694:281:0:o;93836:132::-;93925:31;93938:8;;93948:7;93925:12;:31::i;85589:2721::-;85681:8;;85646:13;;85681:8;;85677:89;;85705:49;;;;;;;;;;;;;;;;;;85589:2721;-1:-1:-1;;85589:2721:0:o;85677:89::-;85778:21;;:::i;:::-;85810:27;;:::i;:::-;85864:1;85850:485;85871:2;85867:1;:6;;;85850:485;;;85909:17;85929:29;85939:1;85941:16;85949:7;85941;:16::i;85929:29::-;85909:49;-1:-1:-1;85909:49:0;85973:4;85978:3;85980:1;85978;:3;:::i;:::-;85973:9;;;;;;;;;:::i;:::-;;;;:14;86010:6;86005:319;86024:1;86022;:3;86005:319;;;86064:24;86091:7;:42;86099:33;86115:16;86123:7;86115;:16::i;86099:33::-;86091:42;;;;;;;;;;;;;;;86134:1;86091:45;;;;;;;;:::i;:::-;;;;;;;;86064:72;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86221:10;86204:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;86194:39;;;;;;86185:3;86168:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;86158:32;;;;;;:75;86155:154;;;86275:9;86285:1;86275:12;;;;;;;:::i;:::-;;;;:14;;;;;;:::i;:::-;;;-1:-1:-1;86155:154:0;-1:-1:-1;86027:3:0;;;;:::i;:::-;;;;86005:319;;;;85880:455;85875:3;;;;;:::i;:::-;;;;85850:485;;;;86347:17;86396:25;86412:4;86417:1;86419;86396:15;:25::i;:::-;86381:40;;;;:::i;:::-;;;86447:25;86463:4;86468:1;86470;86447:15;:25::i;:::-;86432:40;;;;:::i;:::-;;;86498:25;86514:4;86519:1;86521;86498:15;:25::i;:::-;86483:40;;;;:::i;:::-;;;86549:25;86565:4;86570:1;86572;86549:15;:25::i;:::-;86534:40;;;;:::i;:::-;;;86600:25;86616:4;86621:1;86623;86600:15;:25::i;:::-;86585:40;;;;:::i;:::-;;;86651:25;86667:4;86672:1;86674;86651:15;:25::i;:::-;86636:40;;;;:::i;:::-;;;86702:25;86718:4;86723:1;86725;86702:15;:25::i;:::-;86687:40;;;;:::i;:::-;;;86753:25;86769:4;86774:1;86776;86753:15;:25::i;:::-;86738:40;;;;:::i;:::-;;;86804:25;86820:4;86825:1;86827;86804:15;:25::i;:::-;86789:40;;;;:::i;:::-;;;86855:25;86871:4;86876:1;86878;86855:15;:25::i;:::-;86840:40;;;;:::i;:::-;;;86906:25;86922:4;86927:1;86929;86906:15;:25::i;:::-;86891:40;;;;:::i;:::-;;;86957:25;86973:4;86978:1;86980;86957:15;:25::i;:::-;86942:40;;;;:::i;:::-;;;86995:17;87034:9;87029:135;87049:1;87047;:3;87029:135;;;87091:1;87076:9;87086:1;87076:12;;;;;;;:::i;:::-;;;;;:16;87073:80;;;87126:11;;;;:::i;:::-;;;;87073:80;87052:3;;;;:::i;:::-;;;;87029:135;;;-1:-1:-1;87176:40:0;;;;;;;;;;;-1:-1:-1;;;87176:40:0;;;;;;;;87227:27;;;;;;;;87176:20;87227:27;;;87176:40;;87227:27;87267:270;87291:1;87287;:5;87267:270;;;87313:23;87375:12;:1;:10;:12::i;:::-;87346:42;;;;;;;;:::i;:::-;;;;;;;;;;;;;87313:76;;87415:41;87433:9;87443;87453:1;87443:12;;;;;;;:::i;:::-;;;;;87415:17;:41::i;:::-;87404:52;;87504:6;87511:8;87487:37;;;;;;;;;:::i;:::-;;;;;;;;;;;;;87471:54;;87298:239;87294:3;;;;;:::i;:::-;;;;87267:270;;;;87560:44;;;;;;;;;;;;;;-1:-1:-1;;;87560:44:0;;;87592:11;87560:44;;:17;:44::i;:::-;87549:55;;87648:6;87655:8;87631:37;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;87631:37:0;;;;;;87693:62;;;;;;;;;-1:-1:-1;;;87631:37:0;87693:62;;;87631:37;-1:-1:-1;87693:62:0;;87721:33;87737:16;87745:7;87737;:16::i;87721:33::-;87693:62;;:17;:62::i;:::-;87682:73;;87799:6;87806:8;87782:37;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;87782:37:0;;;;;;87844:44;;;;;;;;;-1:-1:-1;;;87782:37:0;87844:44;;;87782:37;-1:-1:-1;87844:44:0;;87878:9;87844:17;:44::i;:::-;87833:55;;87932:6;87939:8;87915:37;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;87915:37:0;;;;;;87977:75;;;;;;;;;-1:-1:-1;;;87915:37:0;87977:75;;;87915:37;-1:-1:-1;87977:75:0;;88048:3;88012:33;88025:16;88033:7;88025;:16::i;:::-;88042:2;88012:12;:33::i;:::-;:39;;;;:::i;:::-;87977:14;:75::i;:::-;87966:86;;88096:6;88103:8;88079:37;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;88079:37:0;;;;;;88141:70;;;;;;;;;-1:-1:-1;;;88079:37:0;88141:70;;;88079:37;-1:-1:-1;88141:70:0;;88207:3;88171:33;88184:16;88192:7;88184;:16::i;:::-;88201:2;88171:12;:33::i;88141:70::-;88130:81;;88255:6;88262:8;88238:37;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;88238:37:0;;;;;;;;;;85589:2721;-1:-1:-1;;;;;;;;85589:2721:0:o;83570:97::-;83614:13;83647:12;83640:19;;;;;:::i;33730:201::-;32894:6;;-1:-1:-1;;;;;32894:6:0;;;;;29307:10;33041:23;33033:68;;;;-1:-1:-1;;;33033:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;33819:22:0;::::1;33811:73;;;::::0;-1:-1:-1;;;33811:73:0;;37741:2:1;33811:73:0::1;::::0;::::1;37723:21:1::0;37780:2;37760:18;;;37753:30;37819:34;37799:18;;;37792:62;-1:-1:-1;;;37870:18:1;;;37863:36;37916:19;;33811:73:0::1;37539:402:1::0;33811:73:0::1;33895:28;33914:8;33895:18;:28::i;67469:224::-:0;67571:4;-1:-1:-1;;;;;;67595:50:0;;-1:-1:-1;;;67595:50:0;;:90;;;67649:36;67673:11;67649:23;:36::i;63758:174::-;63833:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;63833:29:0;-1:-1:-1;;;;;63833:29:0;;;;;;;;:24;;63887:23;63833:24;63887:14;:23::i;:::-;-1:-1:-1;;;;;63878:46:0;;;;;;;;;;;63758:174;;:::o;91959:231::-;92034:13;92065:19;92120:1;92087:30;92100:4;92105:11;92087:30;;:12;:30::i;:::-;:34;;;;:::i;:::-;92065:56;;92139:7;:30;92147:21;92163:4;92147:15;:21::i;:::-;92139:30;;;;;;;;;;;;;;;92170:11;92139:43;;;;;;;;:::i;:::-;;;;;;;;92132:50;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91959:231;;;;:::o;60070:348::-;60163:4;59865:16;;;:7;:16;;;;;;-1:-1:-1;;;;;59865:16:0;60180:73;;;;-1:-1:-1;;;60180:73:0;;40362:2:1;60180:73:0;;;40344:21:1;40401:2;40381:18;;;40374:30;40440:34;40420:18;;;40413:62;-1:-1:-1;;;40491:18:1;;;40484:42;40543:19;;60180:73:0;40160:408:1;60180:73:0;60264:13;60280:23;60295:7;60280:14;:23::i;:::-;60264:39;;60333:5;-1:-1:-1;;;;;60322:16:0;:7;-1:-1:-1;;;;;60322:16:0;;:51;;;;60366:7;-1:-1:-1;;;;;60342:31:0;:20;60354:7;60342:11;:20::i;:::-;-1:-1:-1;;;;;60342:31:0;;60322:51;:87;;;-1:-1:-1;;;;;;57162:25:0;;;57138:4;57162:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;60377:32;57041:164;63062:578;63221:4;-1:-1:-1;;;;;63194:31:0;:23;63209:7;63194:14;:23::i;:::-;-1:-1:-1;;;;;63194:31:0;;63186:85;;;;-1:-1:-1;;;63186:85:0;;44545:2:1;63186:85:0;;;44527:21:1;44584:2;44564:18;;;44557:30;44623:34;44603:18;;;44596:62;-1:-1:-1;;;44674:18:1;;;44667:39;44723:19;;63186:85:0;44343:405:1;63186:85:0;-1:-1:-1;;;;;63290:16:0;;63282:65;;;;-1:-1:-1;;;63282:65:0;;38911:2:1;63282:65:0;;;38893:21:1;38950:2;38930:18;;;38923:30;38989:34;38969:18;;;38962:62;-1:-1:-1;;;39040:18:1;;;39033:34;39084:19;;63282:65:0;38709:400:1;63282:65:0;63360:39;63381:4;63387:2;63391:7;63360:20;:39::i;:::-;63464:29;63481:1;63485:7;63464:8;:29::i;:::-;-1:-1:-1;;;;;63506:15:0;;;;;;:9;:15;;;;;:20;;63525:1;;63506:15;:20;;63525:1;;63506:20;:::i;:::-;;;;-1:-1:-1;;;;;;;63537:13:0;;;;;;:9;:13;;;;;:18;;63554:1;;63537:13;:18;;63554:1;;63537:18;:::i;:::-;;;;-1:-1:-1;;63566:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;63566:21:0;-1:-1:-1;;;;;63566:21:0;;;;;;;;;63605:27;;63566:16;;63605:27;;;;;;;63062:578;;;:::o;31632:120::-;30644:7;;;;31168:41;;;;-1:-1:-1;;;31168:41:0;;36561:2:1;31168:41:0;;;36543:21:1;36600:2;36580:18;;;36573:30;-1:-1:-1;;;36619:18:1;;;36612:50;36679:18;;31168:41:0;36359:344:1;31168:41:0;31691:7:::1;:15:::0;;-1:-1:-1;;31691:15:0::1;::::0;;31722:22:::1;29307:10:::0;31731:12:::1;31722:22;::::0;-1:-1:-1;;;;;33406:32:1;;;33388:51;;33376:2;33361:18;31722:22:0::1;;;;;;;31632:120::o:0;62365:360::-;62425:13;62441:23;62456:7;62441:14;:23::i;:::-;62425:39;;62477:48;62498:5;62513:1;62517:7;62477:20;:48::i;:::-;62566:29;62583:1;62587:7;62566:8;:29::i;:::-;-1:-1:-1;;;;;62608:16:0;;;;;;:9;:16;;;;;:21;;62628:1;;62608:16;:21;;62628:1;;62608:21;:::i;:::-;;;;-1:-1:-1;;62647:16:0;;;;:7;:16;;;;;;62640:23;;-1:-1:-1;;;;;;62640:23:0;;;62681:36;62655:7;;62647:16;-1:-1:-1;;;;;62681:36:0;;;;;62647:16;;62681:36;62414:311;62365:360;:::o;94204:182::-;94284:7;94368:10;94345:6;94353:9;94334:29;;;;;;;;35222:25:1;;;35278:2;35263:18;;35256:34;35210:2;35195:18;;35048:248;94334:29:0;;;;;;;;;;;;;94324:40;;;;;;94316:49;;:62;;;;:::i;26789:723::-;26845:13;27066:10;27062:53;;-1:-1:-1;;27093:10:0;;;;;;;;;;;;-1:-1:-1;;;27093:10:0;;;;;26789:723::o;27062:53::-;27140:5;27125:12;27181:78;27188:9;;27181:78;;27214:8;;;;:::i;:::-;;-1:-1:-1;27237:10:0;;-1:-1:-1;27245:2:0;27237:10;;:::i;:::-;;;27181:78;;;27269:19;27301:6;27291:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27291:17:0;;27269:39;;27319:154;27326:10;;27319:154;;27353:11;27363:1;27353:11;;:::i;:::-;;-1:-1:-1;27422:10:0;27430:2;27422:5;:10;:::i;:::-;27409:24;;:2;:24;:::i;:::-;27396:39;;27379:6;27386;27379:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;27379:56:0;;;;;;;;-1:-1:-1;27450:11:0;27459:2;27450:11;;:::i;:::-;;;27319:154;;23699:190;23824:4;23877;23848:25;23861:5;23868:4;23848:12;:25::i;:::-;:33;;23699:190;-1:-1:-1;;;;23699:190:0:o;13588:1077::-;13698:17;13733:4;-1:-1:-1;;;;;13733:20:0;;13754:14;13770:4;13787:8;12418:1;13776:43;;;;;;;;35222:25:1;;;35278:2;35263:18;;35256:34;35210:2;35195:18;;35048:248;13776:43:0;;;;;;;;;;;;;13733:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;14055:15:0;14139:16;;;:6;:16;;;;;;;;;3458:51;;;;;35532:25:1;;;35573:18;;;35566:34;;;14132:4:0;35616:18:1;;;35609:60;35685:18;;;;35678:34;;;3458:51:0;;;;;;;;;;35504:19:1;;;;3458:51:0;;;3448:62;;;;;;;;;14593:16;;;;;;;:20;;14612:1;14593:20;:::i;:::-;14574:16;;;;:6;:16;;;;;:39;14627:32;14581:8;14651:7;4075:41;;;;;;;9018:19:1;;;;9053:12;;;9046:28;;;;4075:41:0;;;;;;;;;9090:12:1;;;;4075:41:0;;4065:52;;;;;;3908:215;92891:262;92953:5;92992:1;92980:9;92987:2;92980:4;:9;:::i;:::-;:13;92976:170;;;-1:-1:-1;93016:1:0;;92891:262;-1:-1:-1;92891:262:0:o;92976:170::-;93060:1;93048:9;93055:2;93048:4;:9;:::i;:::-;:13;93044:102;;;-1:-1:-1;93084:1:0;;92891:262;-1:-1:-1;92891:262:0:o;93044:102::-;-1:-1:-1;93133:1:0;;92891:262;-1:-1:-1;92891:262:0:o;34091:191::-;34184:6;;;-1:-1:-1;;;;;34201:17:0;;;34184:6;34201:17;;;-1:-1:-1;;;;;;34201:17:0;;;;;;34234:40;;34184:6;;;;;;;;34234:40;;34165:16;;34234:40;34154:128;34091:191;:::o;31373:118::-;30644:7;;;;30898:9;30890:38;;;;-1:-1:-1;;;30890:38:0;;41131:2:1;30890:38:0;;;41113:21:1;41170:2;41150:18;;;41143:30;-1:-1:-1;;;41189:18:1;;;41182:46;41245:18;;30890:38:0;40929:340:1;30890:38:0;31433:7:::1;:14:::0;;-1:-1:-1;;31433:14:0::1;31443:4;31433:14;::::0;;31463:20:::1;31470:12;29307:10:::0;;29227:98;64074:315;64229:8;-1:-1:-1;;;;;64220:17:0;:5;-1:-1:-1;;;;;64220:17:0;;;64212:55;;;;-1:-1:-1;;;64212:55:0;;39316:2:1;64212:55:0;;;39298:21:1;39355:2;39335:18;;;39328:30;39394:27;39374:18;;;39367:55;39439:18;;64212:55:0;39114:349:1;64212:55:0;-1:-1:-1;;;;;64278:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;64278:46:0;;;;;;;;;;64340:41;;34473::1;;;64340::0;;34446:18:1;64340:41:0;;;;;;;64074:315;;;:::o;59148:::-;59305:28;59315:4;59321:2;59325:7;59305:9;:28::i;:::-;59352:48;59375:4;59381:2;59385:7;59394:5;59352:22;:48::i;:::-;59344:111;;;;-1:-1:-1;;;59344:111:0;;;;;;;:::i;60760:110::-;60836:26;60846:2;60850:7;60836:26;;;;;;;;;;;;:9;:26::i;1879:504::-;2053:13;2075:18;2133:9;2165:16;2225:31;2245:9;2225:13;:31::i;:::-;2262:10;2103:174;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2075:203;;2349:26;2369:4;2349:13;:26::i;:::-;2299:77;;;;;;;;:::i;:::-;;;;;;;;;;;;;2285:92;;;1879:504;;;;;;:::o;85148:282::-;85236:5;85329:4;85334:1;85329:7;;;;;;;;;:::i;:::-;;;;;85312:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;85302:36;;;;;;85289:4;85294:1;85289:7;;;;;;;;;:::i;:::-;;;;;85272:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;85262:36;;;;;;:76;85259:164;;;-1:-1:-1;85361:1:0;85354:8;;85259:164;-1:-1:-1;85410:1:0;85403:8;;88505:229;88595:13;88676:9;88703:16;:5;:14;:16::i;:::-;88640:85;;;;;;;;;:::i;:::-;;;;;;;;;;;;;88626:100;;88505:229;;;;:::o;88930:224::-;89017:13;89098:9;89124:16;:5;:14;:16::i;:::-;89062:83;;;;;;;;;:::i;54018:305::-;54120:4;-1:-1:-1;;;;;;54157:40:0;;-1:-1:-1;;;54157:40:0;;:105;;-1:-1:-1;;;;;;;54214:48:0;;-1:-1:-1;;;54214:48:0;54157:105;:158;;;-1:-1:-1;;;;;;;;;;45362:40:0;;;54279:36;45253:157;83250:205;83402:45;83429:4;83435:2;83439:7;83402:26;:45::i;24251:701::-;24334:7;24377:4;24334:7;24392:523;24416:5;:12;24412:1;:16;24392:523;;;24450:20;24473:5;24479:1;24473:8;;;;;;;;:::i;:::-;;;;;;;24450:31;;24516:12;24500;:28;24496:408;;24653:44;;;;;;9018:19:1;;;9053:12;;;9046:28;;;9090:12;;24653:44:0;;;;;;;;;;;;24643:55;;;;;;24628:70;;24496:408;;;24843:44;;;;;;9018:19:1;;;9053:12;;;9046:28;;;9090:12;;24843:44:0;;;;;;;;;;;;24833:55;;;;;;24818:70;;24496:408;-1:-1:-1;24430:3:0;;;;:::i;:::-;;;;24392:523;;;-1:-1:-1;24932:12:0;24251:701;-1:-1:-1;;;24251:701:0:o;64954:799::-;65109:4;-1:-1:-1;;;;;65130:13:0;;35432:20;35480:8;65126:620;;65166:72;;-1:-1:-1;;;65166:72:0;;-1:-1:-1;;;;;65166:36:0;;;;;:72;;29307:10;;65217:4;;65223:7;;65232:5;;65166:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65166:72:0;;;;;;;;-1:-1:-1;;65166:72:0;;;;;;;;;;;;:::i;:::-;;;65162:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65408:13:0;;65404:272;;65451:60;;-1:-1:-1;;;65451:60:0;;;;;;;:::i;65404:272::-;65626:6;65620:13;65611:6;65607:2;65603:15;65596:38;65162:529;-1:-1:-1;;;;;;65289:51:0;-1:-1:-1;;;65289:51:0;;-1:-1:-1;65282:58:0;;65126:620;-1:-1:-1;65730:4:0;65723:11;;61097:321;61227:18;61233:2;61237:7;61227:5;:18::i;:::-;61278:54;61309:1;61313:2;61317:7;61326:5;61278:22;:54::i;:::-;61256:154;;;;-1:-1:-1;;;61256:154:0;;;;;;;:::i;393:1373::-;487:11;;451:13;;509:8;505:23;;-1:-1:-1;;519:9:0;;;;;;;;;-1:-1:-1;519:9:0;;;393:1373;-1:-1:-1;393:1373:0:o;505:23::-;572:18;610:1;599:7;:3;605:1;599:7;:::i;:::-;598:13;;;;:::i;:::-;593:19;;:1;:19;:::i;:::-;572:40;-1:-1:-1;662:19:0;694:15;572:40;707:2;694:15;:::i;:::-;684:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;684:26:0;;662:48;;719:18;740:5;;;;;;;;;;;;;;;;;719:26;;799:1;792:5;788:13;838:2;830:6;826:15;875:1;851:655;892:3;889:1;886:10;851:655;;;933:1;968:12;;;;;962:19;1055:4;1043:2;1039:14;;;;;1021:40;;1015:47;1148:2;1144:14;;;1140:25;;1126:40;;1120:47;1261:1;1257:13;;;1253:24;;1239:39;;1233:46;1365:16;;;;1351:31;;1345:38;1083:1;1079:11;;;1169:4;1116:58;;;1107:68;1192:11;;1229:57;;;1220:67;;;;1304:11;;1341:49;;1332:59;1412:3;1408:13;1433:22;;1495:1;1480:17;;;;926:9;851:655;;;855:30;1532:1;1527:3;1523:11;1547:1;1542:70;;;;1625:1;1620:68;;;;1516:172;;1542:70;-1:-1:-1;;;;;1567:17:0;;1560:43;1542:70;;1620:68;-1:-1:-1;;;;;1645:17:0;;1638:41;1516:172;-1:-1:-1;;;1698:26:0;;;1705:6;393:1373;-1:-1:-1;;;;393:1373:0:o;75083:275::-;75227:45;75254:4;75260:2;75264:7;75227:26;:45::i;:::-;30644:7;;;;75293:9;75285:65;;;;-1:-1:-1;;;75285:65:0;;36149:2:1;75285:65:0;;;36131:21:1;36188:2;36168:18;;;36161:30;36227:34;36207:18;;;36200:62;-1:-1:-1;;;36278:18:1;;;36271:41;36329:19;;75285:65:0;35947:407:1;61754:382:0;-1:-1:-1;;;;;61834:16:0;;61826:61;;;;-1:-1:-1;;;61826:61:0;;43410:2:1;61826:61:0;;;43392:21:1;;;43429:18;;;43422:30;43488:34;43468:18;;;43461:62;43540:18;;61826:61:0;43208:356:1;61826:61:0;59841:4;59865:16;;;:7;:16;;;;;;-1:-1:-1;;;;;59865:16:0;:30;61898:58;;;;-1:-1:-1;;;61898:58:0;;38554:2:1;61898:58:0;;;38536:21:1;38593:2;38573:18;;;38566:30;38632;38612:18;;;38605:58;38680:18;;61898:58:0;38352:352:1;61898:58:0;61969:45;61998:1;62002:2;62006:7;61969:20;:45::i;:::-;-1:-1:-1;;;;;62027:13:0;;;;;;:9;:13;;;;;:18;;62044:1;;62027:13;:18;;62044:1;;62027:18;:::i;:::-;;;;-1:-1:-1;;62056:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;62056:21:0;-1:-1:-1;;;;;62056:21:0;;;;;;;;62095:33;;62056:16;;;62095:33;;62056:16;;62095:33;61754:382;;:::o;69145:589::-;-1:-1:-1;;;;;69351:18:0;;69347:187;;69386:40;69418:7;70561:10;:17;;70534:24;;;;:15;:24;;;;;:44;;;70589:24;;;;;;;;;;;;70457:164;69386:40;69347:187;;;69456:2;-1:-1:-1;;;;;69448:10:0;:4;-1:-1:-1;;;;;69448:10:0;;69444:90;;69475:47;69508:4;69514:7;69475:32;:47::i;:::-;-1:-1:-1;;;;;69548:16:0;;69544:183;;69581:45;69618:7;69581:36;:45::i;69544:183::-;69654:4;-1:-1:-1;;;;;69648:10:0;:2;-1:-1:-1;;;;;69648:10:0;;69644:83;;69675:40;69703:2;69707:7;69675:27;:40::i;71248:988::-;71514:22;71564:1;71539:22;71556:4;71539:16;:22::i;:::-;:26;;;;:::i;:::-;71576:18;71597:26;;;:17;:26;;;;;;71514:51;;-1:-1:-1;71730:28:0;;;71726:328;;-1:-1:-1;;;;;71797:18:0;;71775:19;71797:18;;;:12;:18;;;;;;;;:34;;;;;;;;;71848:30;;;;;;:44;;;71965:30;;:17;:30;;;;;:43;;;71726:328;-1:-1:-1;72150:26:0;;;;:17;:26;;;;;;;;72143:33;;;-1:-1:-1;;;;;72194:18:0;;;;;:12;:18;;;;;:34;;;;;;;72187:41;71248:988::o;72531:1079::-;72809:10;:17;72784:22;;72809:21;;72829:1;;72809:21;:::i;:::-;72841:18;72862:24;;;:15;:24;;;;;;73235:10;:26;;72784:46;;-1:-1:-1;72862:24:0;;72784:46;;73235:26;;;;;;:::i;:::-;;;;;;;;;73213:48;;73299:11;73274:10;73285;73274:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;73379:28;;;:15;:28;;;;;;;:41;;;73551:24;;;;;73544:31;73586:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;72602:1008;;;72531:1079;:::o;70035:221::-;70120:14;70137:20;70154:2;70137:16;:20::i;:::-;-1:-1:-1;;;;;70168:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;70213:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;70035:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;14:406:1;78:5;112:18;104:6;101:30;98:56;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:45;;;309:1;306;299:12;268:45;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;14:406;;;;;:::o;425:156::-;491:20;;551:4;540:16;;530:27;;520:55;;571:1;568;561:12;586:247;645:6;698:2;686:9;677:7;673:23;669:32;666:52;;;714:1;711;704:12;666:52;753:9;740:23;772:31;797:5;772:31;:::i;838:323::-;914:6;922;975:2;963:9;954:7;950:23;946:32;943:52;;;991:1;988;981:12;943:52;1030:9;1017:23;1049:31;1074:5;1049:31;:::i;:::-;1099:5;1151:2;1136:18;;;;1123:32;;-1:-1:-1;;;838:323:1:o;1166:388::-;1234:6;1242;1295:2;1283:9;1274:7;1270:23;1266:32;1263:52;;;1311:1;1308;1301:12;1263:52;1350:9;1337:23;1369:31;1394:5;1369:31;:::i;:::-;1419:5;-1:-1:-1;1476:2:1;1461:18;;1448:32;1489:33;1448:32;1489:33;:::i;:::-;1541:7;1531:17;;;1166:388;;;;;:::o;1559:456::-;1636:6;1644;1652;1705:2;1693:9;1684:7;1680:23;1676:32;1673:52;;;1721:1;1718;1711:12;1673:52;1760:9;1747:23;1779:31;1804:5;1779:31;:::i;:::-;1829:5;-1:-1:-1;1886:2:1;1871:18;;1858:32;1899:33;1858:32;1899:33;:::i;:::-;1559:456;;1951:7;;-1:-1:-1;;;2005:2:1;1990:18;;;;1977:32;;1559:456::o;2020:794::-;2115:6;2123;2131;2139;2192:3;2180:9;2171:7;2167:23;2163:33;2160:53;;;2209:1;2206;2199:12;2160:53;2248:9;2235:23;2267:31;2292:5;2267:31;:::i;:::-;2317:5;-1:-1:-1;2374:2:1;2359:18;;2346:32;2387:33;2346:32;2387:33;:::i;:::-;2439:7;-1:-1:-1;2493:2:1;2478:18;;2465:32;;-1:-1:-1;2548:2:1;2533:18;;2520:32;2575:18;2564:30;;2561:50;;;2607:1;2604;2597:12;2561:50;2630:22;;2683:4;2675:13;;2671:27;-1:-1:-1;2661:55:1;;2712:1;2709;2702:12;2661:55;2735:73;2800:7;2795:2;2782:16;2777:2;2773;2769:11;2735:73;:::i;:::-;2725:83;;;2020:794;;;;;;;:::o;2819:382::-;2884:6;2892;2945:2;2933:9;2924:7;2920:23;2916:32;2913:52;;;2961:1;2958;2951:12;2913:52;3000:9;2987:23;3019:31;3044:5;3019:31;:::i;:::-;3069:5;-1:-1:-1;3126:2:1;3111:18;;3098:32;3139:30;3098:32;3139:30;:::i;3526:1027::-;3619:6;3627;3680:2;3668:9;3659:7;3655:23;3651:32;3648:52;;;3696:1;3693;3686:12;3648:52;3736:9;3723:23;3765:18;3806:2;3798:6;3795:14;3792:34;;;3822:1;3819;3812:12;3792:34;3860:6;3849:9;3845:22;3835:32;;3905:7;3898:4;3894:2;3890:13;3886:27;3876:55;;3927:1;3924;3917:12;3876:55;3963:2;3950:16;3985:4;4008:2;4004;4001:10;3998:36;;;4014:18;;:::i;:::-;4060:2;4057:1;4053:10;4043:20;;4083:28;4107:2;4103;4099:11;4083:28;:::i;:::-;4145:15;;;4176:12;;;;4208:11;;;4238;;;4234:20;;4231:33;-1:-1:-1;4228:53:1;;;4277:1;4274;4267:12;4228:53;4299:1;4290:10;;4309:163;4323:2;4320:1;4317:9;4309:163;;;4380:17;;4368:30;;4341:1;4334:9;;;;;4418:12;;;;4450;;4309:163;;;-1:-1:-1;4491:5:1;4528:18;;;;4515:32;;-1:-1:-1;;;;;;;3526:1027:1:o;4558:241::-;4614:6;4667:2;4655:9;4646:7;4642:23;4638:32;4635:52;;;4683:1;4680;4673:12;4635:52;4722:9;4709:23;4741:28;4763:5;4741:28;:::i;4804:245::-;4871:6;4924:2;4912:9;4903:7;4899:23;4895:32;4892:52;;;4940:1;4937;4930:12;4892:52;4972:9;4966:16;4991:28;5013:5;4991:28;:::i;5054:248::-;5122:6;5130;5183:2;5171:9;5162:7;5158:23;5154:32;5151:52;;;5199:1;5196;5189:12;5151:52;-1:-1:-1;;5222:23:1;;;5292:2;5277:18;;;5264:32;;-1:-1:-1;5054:248:1:o;5307:245::-;5365:6;5418:2;5406:9;5397:7;5393:23;5389:32;5386:52;;;5434:1;5431;5424:12;5386:52;5473:9;5460:23;5492:30;5516:5;5492:30;:::i;5557:249::-;5626:6;5679:2;5667:9;5658:7;5654:23;5650:32;5647:52;;;5695:1;5692;5685:12;5647:52;5727:9;5721:16;5746:30;5770:5;5746:30;:::i;5811:450::-;5880:6;5933:2;5921:9;5912:7;5908:23;5904:32;5901:52;;;5949:1;5946;5939:12;5901:52;5989:9;5976:23;6022:18;6014:6;6011:30;6008:50;;;6054:1;6051;6044:12;6008:50;6077:22;;6130:4;6122:13;;6118:27;-1:-1:-1;6108:55:1;;6159:1;6156;6149:12;6108:55;6182:73;6247:7;6242:2;6229:16;6224:2;6220;6216:11;6182:73;:::i;6266:180::-;6325:6;6378:2;6366:9;6357:7;6353:23;6349:32;6346:52;;;6394:1;6391;6384:12;6346:52;-1:-1:-1;6417:23:1;;6266:180;-1:-1:-1;6266:180:1:o;6451:184::-;6521:6;6574:2;6562:9;6553:7;6549:23;6545:32;6542:52;;;6590:1;6587;6580:12;6542:52;-1:-1:-1;6613:16:1;;6451:184;-1:-1:-1;6451:184:1:o;6640:182::-;6697:6;6750:2;6738:9;6729:7;6725:23;6721:32;6718:52;;;6766:1;6763;6756:12;6718:52;6789:27;6806:9;6789:27;:::i;6827:450::-;6906:6;6914;6922;6930;6983:3;6971:9;6962:7;6958:23;6954:33;6951:53;;;7000:1;6997;6990:12;6951:53;7023:27;7040:9;7023:27;:::i;:::-;7013:37;;7097:2;7086:9;7082:18;7069:32;7059:42;;7151:2;7140:9;7136:18;7123:32;7164:28;7186:5;7164:28;:::i;:::-;7211:5;-1:-1:-1;7235:36:1;7267:2;7252:18;;7235:36;:::i;:::-;7225:46;;6827:450;;;;;;;:::o;7282:318::-;7357:6;7365;7373;7426:2;7414:9;7405:7;7401:23;7397:32;7394:52;;;7442:1;7439;7432:12;7394:52;7465:27;7482:9;7465:27;:::i;:::-;7455:37;7539:2;7524:18;;7511:32;;-1:-1:-1;7590:2:1;7575:18;;;7562:32;;7282:318;-1:-1:-1;;;7282:318:1:o;7605:755::-;7705:6;7713;7721;7729;7782:2;7770:9;7761:7;7757:23;7753:32;7750:52;;;7798:1;7795;7788:12;7750:52;7821:27;7838:9;7821:27;:::i;:::-;7811:37;;7867:36;7899:2;7888:9;7884:18;7867:36;:::i;:::-;7857:46;;7954:2;7943:9;7939:18;7926:32;7977:18;8018:2;8010:6;8007:14;8004:34;;;8034:1;8031;8024:12;8004:34;8072:6;8061:9;8057:22;8047:32;;8117:7;8110:4;8106:2;8102:13;8098:27;8088:55;;8139:1;8136;8129:12;8088:55;8179:2;8166:16;8205:2;8197:6;8194:14;8191:34;;;8221:1;8218;8211:12;8191:34;8274:7;8269:2;8259:6;8256:1;8252:14;8248:2;8244:23;8240:32;8237:45;8234:65;;;8295:1;8292;8285:12;8234:65;7605:755;;;;-1:-1:-1;;8326:2:1;8318:11;;-1:-1:-1;;;7605:755:1:o;8365:257::-;8406:3;8444:5;8438:12;8471:6;8466:3;8459:19;8487:63;8543:6;8536:4;8531:3;8527:14;8520:4;8513:5;8509:16;8487:63;:::i;:::-;8604:2;8583:15;-1:-1:-1;;8579:29:1;8570:39;;;;8611:4;8566:50;;8365:257;-1:-1:-1;;8365:257:1:o;9365:276::-;9496:3;9534:6;9528:13;9550:53;9596:6;9591:3;9584:4;9576:6;9572:17;9550:53;:::i;:::-;9619:16;;;;;9365:276;-1:-1:-1;;9365:276:1:o;9646:664::-;9873:3;9911:6;9905:13;9927:53;9973:6;9968:3;9961:4;9953:6;9949:17;9927:53;:::i;:::-;10043:13;;10002:16;;;;10065:57;10043:13;10002:16;10099:4;10087:17;;10065:57;:::i;:::-;10189:13;;10144:20;;;10211:57;10189:13;10144:20;10245:4;10233:17;;10211:57;:::i;:::-;10284:20;;9646:664;-1:-1:-1;;;;;9646:664:1:o;10315:1052::-;10638:3;10676:6;10670:13;10692:53;10738:6;10733:3;10726:4;10718:6;10714:17;10692:53;:::i;:::-;10808:13;;10767:16;;;;10830:57;10808:13;10767:16;10864:4;10852:17;;10830:57;:::i;:::-;10954:13;;10909:20;;;10976:57;10954:13;10909:20;11010:4;10998:17;;10976:57;:::i;:::-;11100:13;;11055:20;;;11122:57;11100:13;11055:20;11156:4;11144:17;;11122:57;:::i;:::-;11246:13;;11201:20;;;11268:57;11246:13;11201:20;11302:4;11290:17;;11268:57;:::i;:::-;11341:20;;10315:1052;-1:-1:-1;;;;;;;10315:1052:1:o;11372:1425::-;11844:3;11882:6;11876:13;11908:4;11921:51;11965:6;11960:3;11955:2;11947:6;11943:15;11921:51;:::i;:::-;12035:13;;11994:16;;;;12057:55;12035:13;11994:16;12079:15;;;12057:55;:::i;:::-;12179:13;;12134:20;;;12201:55;12179:13;12134:20;12223:15;;;12201:55;:::i;:::-;12323:13;;12278:20;;;12345:55;12323:13;12278:20;12367:15;;;12345:55;:::i;:::-;12467:13;;12422:20;;;12489:55;12467:13;12422:20;12511:15;;;12489:55;:::i;:::-;12611:13;;12566:20;;;12633:55;12611:13;12566:20;12655:15;;;12633:55;:::i;:::-;-1:-1:-1;;;12710:20:1;;12739:23;;;-1:-1:-1;12789:1:1;12778:13;;11372:1425;-1:-1:-1;;;;;;;;11372:1425:1:o;12802:633::-;13082:3;13120:6;13114:13;13136:53;13182:6;13177:3;13170:4;13162:6;13158:17;13136:53;:::i;:::-;13252:13;;13211:16;;;;13274:57;13252:13;13211:16;13308:4;13296:17;;13274:57;:::i;:::-;-1:-1:-1;;;13353:20:1;;13382:18;;;13427:1;13416:13;;12802:633;-1:-1:-1;;;;12802:633:1:o;13440:::-;13720:3;13758:6;13752:13;13774:53;13820:6;13815:3;13808:4;13800:6;13796:17;13774:53;:::i;:::-;13890:13;;13849:16;;;;13912:57;13890:13;13849:16;13946:4;13934:17;;13912:57;:::i;:::-;-1:-1:-1;;;13991:20:1;;14020:18;;;14065:1;14054:13;;13440:633;-1:-1:-1;;;;13440:633:1:o;14078:::-;14358:3;14396:6;14390:13;14412:53;14458:6;14453:3;14446:4;14438:6;14434:17;14412:53;:::i;:::-;14528:13;;14487:16;;;;14550:57;14528:13;14487:16;14584:4;14572:17;;14550:57;:::i;:::-;-1:-1:-1;;;14629:20:1;;14658:18;;;14703:1;14692:13;;14078:633;-1:-1:-1;;;;14078:633:1:o;14716:734::-;-1:-1:-1;;;;;;;;;;;15074:3:1;15067:79;15185:40;15180:3;15176:50;15171:2;15166:3;15162:12;15155:72;15049:3;15256:6;15250:13;15272:60;15325:6;15320:2;15315:3;15311:12;15306:2;15298:6;15294:15;15272:60;:::i;:::-;-1:-1:-1;;;15391:2:1;15351:16;;;;15383:11;;;15376:41;-1:-1:-1;15441:2:1;15433:11;;14716:734;-1:-1:-1;14716:734:1:o;15455:994::-;-1:-1:-1;;;15955:57:1;;16035:13;;15937:3;;16057:62;16035:13;16107:2;16098:12;;16091:4;16079:17;;16057:62;:::i;:::-;-1:-1:-1;;;16178:2:1;16138:16;;;16170:11;;;16163:61;16249:13;;16271:63;16249:13;16320:2;16312:11;;16305:4;16293:17;;16271:63;:::i;:::-;-1:-1:-1;;;16394:2:1;16353:17;;;;16386:11;;;16379:35;16438:4;16430:13;;15455:994;-1:-1:-1;;;;15455:994:1:o;16454:979::-;-1:-1:-1;;;16954:57:1;;17034:13;;16936:3;;17056:62;17034:13;17106:2;17097:12;;17090:4;17078:17;;17056:62;:::i;:::-;-1:-1:-1;;;17177:2:1;17137:16;;;17169:11;;;17162:59;17246:13;;17268:63;17246:13;17317:2;17309:11;;17302:4;17290:17;;17268:63;:::i;:::-;-1:-1:-1;;;17391:2:1;17350:17;;;;17383:11;;;17376:24;17424:2;17416:11;;16454:979;-1:-1:-1;;;;16454:979:1:o;17438:1739::-;-1:-1:-1;;;18236:43:1;;18302:13;;18218:3;;18324:61;18302:13;18374:1;18365:11;;18358:4;18346:17;;18324:61;:::i;:::-;-1:-1:-1;;;18444:1:1;18404:16;;;18436:10;;;18429:66;18520:13;;18542:63;18520:13;18591:2;18583:11;;18576:4;18564:17;;18542:63;:::i;:::-;18670:66;18665:2;18624:17;;;;18657:11;;;18650:87;-1:-1:-1;;;18761:2:1;18753:11;;18746:29;18800:13;;18822:63;18800:13;18871:2;18863:11;;18856:4;18844:17;;18822:63;:::i;:::-;-1:-1:-1;;;18945:2:1;18904:17;;;;18937:11;;;18930:35;18990:13;;19012:63;18990:13;19061:2;19053:11;;19046:4;19034:17;;19012:63;:::i;:::-;-1:-1:-1;;;19135:2:1;19094:17;;;;19127:11;;;19120:24;19168:2;19160:11;;17438:1739;-1:-1:-1;;;;;;17438:1739:1:o;19599:734::-;-1:-1:-1;;;;;;;;;;;19957:3:1;19950:79;20068:40;20063:3;20059:50;20054:2;20049:3;20045:12;20038:72;19932:3;20139:6;20133:13;20155:60;20208:6;20203:2;20198:3;20194:12;20189:2;20181:6;20177:15;20155:60;:::i;20338:719::-;20701:66;20696:3;20689:79;20807:40;20802:3;20798:50;20793:2;20788:3;20784:12;20777:72;20671:3;20878:6;20872:13;20894:60;20947:6;20942:2;20937:3;20933:12;20928:2;20920:6;20916:15;20894:60;:::i;:::-;-1:-1:-1;;;21013:2:1;20973:16;;;;21005:11;;;20998:26;-1:-1:-1;21048:2:1;21040:11;;20338:719;-1:-1:-1;20338:719:1:o;21062:732::-;-1:-1:-1;;;;;;;;;;;21420:3:1;21413:79;21531:38;21526:3;21522:48;21517:2;21512:3;21508:12;21501:70;21395:3;21600:6;21594:13;21616:60;21669:6;21664:2;21659:3;21655:12;21650:2;21642:6;21638:15;21616:60;:::i;:::-;-1:-1:-1;;;21735:2:1;21695:16;;;;21727:11;;;21720:41;-1:-1:-1;21785:2:1;21777:11;;21062:732;-1:-1:-1;21062:732:1:o;21799:::-;-1:-1:-1;;;;;;;;;;;22157:3:1;22150:79;22268:38;22263:3;22259:48;22254:2;22249:3;22245:12;22238:70;22132:3;22337:6;22331:13;22353:60;22406:6;22401:2;22396:3;22392:12;22387:2;22379:6;22375:15;22353:60;:::i;22536:425::-;-1:-1:-1;;;22793:3:1;22786:23;22768:3;22838:6;22832:13;22854:61;22908:6;22904:1;22899:3;22895:11;22888:4;22880:6;22876:17;22854:61;:::i;:::-;22935:16;;;;22953:1;22931:24;;22536:425;-1:-1:-1;;22536:425:1:o;22966:734::-;-1:-1:-1;;;;;;;;;;;23324:3:1;23317:79;23435:40;23430:3;23426:50;23421:2;23416:3;23412:12;23405:72;23299:3;23506:6;23500:13;23522:60;23575:6;23570:2;23565:3;23561:12;23556:2;23548:6;23544:15;23522:60;:::i;23705:734::-;-1:-1:-1;;;;;;;;;;;24063:3:1;24056:79;24174:40;24169:3;24165:50;24160:2;24155:3;24151:12;24144:72;24038:3;24245:6;24239:13;24261:60;24314:6;24309:2;24304:3;24300:12;24295:2;24287:6;24283:15;24261:60;:::i;24444:1274::-;-1:-1:-1;;;25093:35:1;;25151:13;;25075:3;;25173:61;25151:13;25223:1;25214:11;;25207:4;25195:17;;25173:61;:::i;:::-;25262:6;25257:3;25253:16;25243:26;;-1:-1:-1;;;25319:2:1;25315:1;25311:2;25307:10;25300:22;25353:6;25347:13;25369:62;25422:8;25418:1;25414:2;25410:10;25403:4;25395:6;25391:17;25369:62;:::i;:::-;25491:1;25450:17;;25483:10;;;25476:22;25523:13;;25545:62;25523:13;25594:1;25586:10;;25579:4;25567:17;;25545:62;:::i;:::-;-1:-1:-1;;;25667:1:1;25626:17;;;;25659:10;;;25652:34;25710:1;25702:10;;24444:1274;-1:-1:-1;;;;;24444:1274:1:o;25723:730::-;-1:-1:-1;;;;;;;;;;;26081:3:1;26074:79;26192:36;26187:3;26183:46;26178:2;26173:3;26169:12;26162:68;26056:3;26259:6;26253:13;26275:60;26328:6;26323:2;26318:3;26314:12;26309:2;26301:6;26297:15;26275:60;:::i;:::-;-1:-1:-1;;;26394:2:1;26354:16;;;;26386:11;;;26379:41;-1:-1:-1;26444:2:1;26436:11;;25723:730;-1:-1:-1;25723:730:1:o;26458:732::-;-1:-1:-1;;;;;;;;;;;26816:3:1;26809:79;26927:38;26922:3;26918:48;26913:2;26908:3;26904:12;26897:70;26791:3;26996:6;26990:13;27012:60;27065:6;27060:2;27055:3;27051:12;27046:2;27038:6;27034:15;27012:60;:::i;28029:448::-;28291:31;28286:3;28279:44;28261:3;28352:6;28346:13;28368:62;28423:6;28418:2;28413:3;28409:12;28402:4;28394:6;28390:17;28368:62;:::i;:::-;28450:16;;;;28468:2;28446:25;;28029:448;-1:-1:-1;;28029:448:1:o;28482:732::-;-1:-1:-1;;;;;;;;;;;28840:3:1;28833:79;28951:38;28946:3;28942:48;28937:2;28932:3;28928:12;28921:70;28815:3;29020:6;29014:13;29036:60;29089:6;29084:2;29079:3;29075:12;29070:2;29062:6;29058:15;29036:60;:::i;29219:429::-;-1:-1:-1;;;29476:3:1;29469:25;29451:3;29523:6;29517:13;29539:62;29594:6;29589:2;29584:3;29580:12;29573:4;29565:6;29561:17;29539:62;:::i;:::-;29621:16;;;;29639:2;29617:25;;29219:429;-1:-1:-1;;29219:429:1:o;29653:717::-;30016:66;30011:3;30004:79;30122:38;30117:3;30113:48;30108:2;30103:3;30099:12;30092:70;29986:3;30191:6;30185:13;30207:60;30260:6;30255:2;30250:3;30246:12;30241:2;30233:6;30229:15;30207:60;:::i;:::-;-1:-1:-1;;;30326:2:1;30286:16;;;;30318:11;;;30311:26;-1:-1:-1;30361:2:1;30353:11;;29653:717;-1:-1:-1;29653:717:1:o;30375:::-;30738:66;30733:3;30726:79;30844:38;30839:3;30835:48;30830:2;30825:3;30821:12;30814:70;30708:3;30913:6;30907:13;30929:60;30982:6;30977:2;30972:3;30968:12;30963:2;30955:6;30951:15;30929:60;:::i;31097:713::-;31460:66;31455:3;31448:79;31566:34;31561:3;31557:44;31552:2;31547:3;31543:12;31536:66;31430:3;31631:6;31625:13;31647:60;31700:6;31695:2;31690:3;31686:12;31681:2;31673:6;31669:15;31647:60;:::i;:::-;-1:-1:-1;;;31766:2:1;31726:16;;;;31758:11;;;31751:26;-1:-1:-1;31801:2:1;31793:11;;31097:713;-1:-1:-1;31097:713:1:o;31815:1422::-;32269:66;32264:3;32257:79;32239:3;32355:2;32387:66;32382:2;32377:3;32373:12;32366:88;-1:-1:-1;;;32479:2:1;32474:3;32470:12;32463:25;32507:2;32538:6;32532:13;32554:60;32607:6;32602:2;32597:3;32593:12;32588:2;32580:6;32576:15;32554:60;:::i;:::-;32674:13;;32633:16;;;;32696:61;32674:13;32735:11;;;32718:15;;;32696:61;:::i;:::-;32818:13;;32776:17;;;32840:61;32818:13;32879:11;;;32862:15;;;32840:61;:::i;:::-;32962:13;;32920:17;;;32984:61;32962:13;33023:11;;;33006:15;;;32984:61;:::i;:::-;33106:13;;33064:17;;;33128:61;33106:13;33167:11;;;33150:15;;;33128:61;:::i;:::-;33209:17;33205:26;;31815:1422;-1:-1:-1;;;;;;;;31815:1422:1:o;33450:488::-;-1:-1:-1;;;;;33719:15:1;;;33701:34;;33771:15;;33766:2;33751:18;;33744:43;33818:2;33803:18;;33796:34;;;33866:3;33861:2;33846:18;;33839:31;;;33644:4;;33887:45;;33912:19;;33904:6;33887:45;:::i;:::-;33879:53;33450:488;-1:-1:-1;;;;;;33450:488:1:o;33943:385::-;34175:1;34171;34166:3;34162:11;34158:19;34150:6;34146:32;34135:9;34128:51;34215:6;34210:2;34199:9;34195:18;34188:34;34258:2;34253;34242:9;34238:18;34231:30;34109:4;34278:44;34318:2;34307:9;34303:18;34295:6;34278:44;:::i;:::-;34270:52;33943:385;-1:-1:-1;;;;;33943:385:1:o;35723:219::-;35872:2;35861:9;35854:21;35835:4;35892:44;35932:2;35921:9;35917:18;35909:6;35892:44;:::i;37120:414::-;37322:2;37304:21;;;37361:2;37341:18;;;37334:30;37400:34;37395:2;37380:18;;37373:62;-1:-1:-1;;;37466:2:1;37451:18;;37444:48;37524:3;37509:19;;37120:414::o;43982:356::-;44184:2;44166:21;;;44203:18;;;44196:30;44262:34;44257:2;44242:18;;44235:62;44329:2;44314:18;;43982:356::o;45873:413::-;46075:2;46057:21;;;46114:2;46094:18;;;46087:30;46153:34;46148:2;46133:18;;46126:62;-1:-1:-1;;;46219:2:1;46204:18;;46197:47;46276:3;46261:19;;45873:413::o;48087:275::-;48158:2;48152:9;48223:2;48204:13;;-1:-1:-1;;48200:27:1;48188:40;;48258:18;48243:34;;48279:22;;;48240:62;48237:88;;;48305:18;;:::i;:::-;48341:2;48334:22;48087:275;;-1:-1:-1;48087:275:1:o;48367:128::-;48407:3;48438:1;48434:6;48431:1;48428:13;48425:39;;;48444:18;;:::i;:::-;-1:-1:-1;48480:9:1;;48367:128::o;48500:204::-;48538:3;48574:4;48571:1;48567:12;48606:4;48603:1;48599:12;48641:3;48635:4;48631:14;48626:3;48623:23;48620:49;;;48649:18;;:::i;:::-;48685:13;;48500:204;-1:-1:-1;;;48500:204:1:o;48709:120::-;48749:1;48775;48765:35;;48780:18;;:::i;:::-;-1:-1:-1;48814:9:1;;48709:120::o;48834:168::-;48874:7;48940:1;48936;48932:6;48928:14;48925:1;48922:21;48917:1;48910:9;48903:17;48899:45;48896:71;;;48947:18;;:::i;:::-;-1:-1:-1;48987:9:1;;48834:168::o;49007:125::-;49047:4;49075:1;49072;49069:8;49066:34;;;49080:18;;:::i;:::-;-1:-1:-1;49117:9:1;;49007:125::o;49137:195::-;49175:4;49212;49209:1;49205:12;49244:4;49241:1;49237:12;49269:3;49264;49261:12;49258:38;;;49276:18;;:::i;:::-;49313:13;;;49137:195;-1:-1:-1;;;49137:195:1:o;49337:258::-;49409:1;49419:113;49433:6;49430:1;49427:13;49419:113;;;49509:11;;;49503:18;49490:11;;;49483:39;49455:2;49448:10;49419:113;;;49550:6;49547:1;49544:13;49541:48;;;-1:-1:-1;;49585:1:1;49567:16;;49560:27;49337:258::o;49600:380::-;49679:1;49675:12;;;;49722;;;49743:61;;49797:4;49789:6;49785:17;49775:27;;49743:61;49850:2;49842:6;49839:14;49819:18;49816:38;49813:161;;;49896:10;49891:3;49887:20;49884:1;49877:31;49931:4;49928:1;49921:15;49959:4;49956:1;49949:15;49813:161;;49600:380;;;:::o;49985:135::-;50024:3;-1:-1:-1;;50045:17:1;;50042:43;;;50065:18;;:::i;:::-;-1:-1:-1;50112:1:1;50101:13;;49985:135::o;50125:175::-;50162:3;50206:4;50199:5;50195:16;50235:4;50226:7;50223:17;50220:43;;;50243:18;;:::i;:::-;50292:1;50279:15;;50125:175;-1:-1:-1;;50125:175:1:o;50305:112::-;50337:1;50363;50353:35;;50368:18;;:::i;:::-;-1:-1:-1;50402:9:1;;50305:112::o;50422:127::-;50483:10;50478:3;50474:20;50471:1;50464:31;50514:4;50511:1;50504:15;50538:4;50535:1;50528:15;50554:127;50615:10;50610:3;50606:20;50603:1;50596:31;50646:4;50643:1;50636:15;50670:4;50667:1;50660:15;50686:127;50747:10;50742:3;50738:20;50735:1;50728:31;50778:4;50775:1;50768:15;50802:4;50799:1;50792:15;50818:127;50879:10;50874:3;50870:20;50867:1;50860:31;50910:4;50907:1;50900:15;50934:4;50931:1;50924:15;50950:127;51011:10;51006:3;51002:20;50999:1;50992:31;51042:4;51039:1;51032:15;51066:4;51063:1;51056:15;51082:131;-1:-1:-1;;;;;51157:31:1;;51147:42;;51137:70;;51203:1;51200;51193:12;51218:118;51304:5;51297:13;51290:21;51283:5;51280:32;51270:60;;51326:1;51323;51316:12;51341:131;-1:-1:-1;;;;;;51415:32:1;;51405:43;;51395:71;;51462:1;51459;51452:12

Swarm Source

ipfs://183c932e9248e9bc2474e40669e0d603165095cbea4b6cbfa8ac3c65a8ca66ed
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.