ETH Price: $3,439.35 (-0.19%)

Token

Crazy Owl (COWL)

Overview

Max Total Supply

0 COWL

Holders

10

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
CrazyOwl

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at zkevm.polygonscan.com on 2023-04-26
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/governance/utils/IVotes.sol


// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)
pragma solidity ^0.8.0;

/**
 * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.
 *
 * _Available since v4.5._
 */
interface IVotes {
    /**
     * @dev Emitted when an account changes their delegate.
     */
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /**
     * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.
     */
    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) external view returns (uint256);

    /**
     * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).
     */
    function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);

    /**
     * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     */
    function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) external view returns (address);

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) external;

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.2._
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v2.5._
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.2._
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v2.5._
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v2.5._
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v2.5._
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v2.5._
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     *
     * _Available since v3.0._
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     *
     * _Available since v4.7._
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     *
     * _Available since v4.7._
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     *
     * _Available since v4.7._
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     *
     * _Available since v4.7._
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     *
     * _Available since v4.7._
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     *
     * _Available since v4.7._
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     *
     * _Available since v4.7._
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     *
     * _Available since v4.7._
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     *
     * _Available since v4.7._
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     *
     * _Available since v4.7._
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     *
     * _Available since v4.7._
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     *
     * _Available since v4.7._
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
     * Counterpart to Solidity's `int152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     *
     * _Available since v4.7._
     */
    function toInt152(int256 value) internal pure returns (int152 downcasted) {
        downcasted = int152(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
    }

    /**
     * @dev Returns the downcasted int144 from int256, reverting on
     * overflow (when the input is less than smallest int144 or
     * greater than largest int144).
     *
     * Counterpart to Solidity's `int144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     *
     * _Available since v4.7._
     */
    function toInt144(int256 value) internal pure returns (int144 downcasted) {
        downcasted = int144(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
    }

    /**
     * @dev Returns the downcasted int136 from int256, reverting on
     * overflow (when the input is less than smallest int136 or
     * greater than largest int136).
     *
     * Counterpart to Solidity's `int136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     *
     * _Available since v4.7._
     */
    function toInt136(int256 value) internal pure returns (int136 downcasted) {
        downcasted = int136(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128 downcasted) {
        downcasted = int128(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
    }

    /**
     * @dev Returns the downcasted int120 from int256, reverting on
     * overflow (when the input is less than smallest int120 or
     * greater than largest int120).
     *
     * Counterpart to Solidity's `int120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     *
     * _Available since v4.7._
     */
    function toInt120(int256 value) internal pure returns (int120 downcasted) {
        downcasted = int120(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
    }

    /**
     * @dev Returns the downcasted int112 from int256, reverting on
     * overflow (when the input is less than smallest int112 or
     * greater than largest int112).
     *
     * Counterpart to Solidity's `int112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     *
     * _Available since v4.7._
     */
    function toInt112(int256 value) internal pure returns (int112 downcasted) {
        downcasted = int112(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
    }

    /**
     * @dev Returns the downcasted int104 from int256, reverting on
     * overflow (when the input is less than smallest int104 or
     * greater than largest int104).
     *
     * Counterpart to Solidity's `int104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     *
     * _Available since v4.7._
     */
    function toInt104(int256 value) internal pure returns (int104 downcasted) {
        downcasted = int104(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
    }

    /**
     * @dev Returns the downcasted int96 from int256, reverting on
     * overflow (when the input is less than smallest int96 or
     * greater than largest int96).
     *
     * Counterpart to Solidity's `int96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     *
     * _Available since v4.7._
     */
    function toInt96(int256 value) internal pure returns (int96 downcasted) {
        downcasted = int96(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
    }

    /**
     * @dev Returns the downcasted int88 from int256, reverting on
     * overflow (when the input is less than smallest int88 or
     * greater than largest int88).
     *
     * Counterpart to Solidity's `int88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     *
     * _Available since v4.7._
     */
    function toInt88(int256 value) internal pure returns (int88 downcasted) {
        downcasted = int88(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
    }

    /**
     * @dev Returns the downcasted int80 from int256, reverting on
     * overflow (when the input is less than smallest int80 or
     * greater than largest int80).
     *
     * Counterpart to Solidity's `int80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     *
     * _Available since v4.7._
     */
    function toInt80(int256 value) internal pure returns (int80 downcasted) {
        downcasted = int80(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
    }

    /**
     * @dev Returns the downcasted int72 from int256, reverting on
     * overflow (when the input is less than smallest int72 or
     * greater than largest int72).
     *
     * Counterpart to Solidity's `int72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     *
     * _Available since v4.7._
     */
    function toInt72(int256 value) internal pure returns (int72 downcasted) {
        downcasted = int72(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64 downcasted) {
        downcasted = int64(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
    }

    /**
     * @dev Returns the downcasted int56 from int256, reverting on
     * overflow (when the input is less than smallest int56 or
     * greater than largest int56).
     *
     * Counterpart to Solidity's `int56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     *
     * _Available since v4.7._
     */
    function toInt56(int256 value) internal pure returns (int56 downcasted) {
        downcasted = int56(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
    }

    /**
     * @dev Returns the downcasted int48 from int256, reverting on
     * overflow (when the input is less than smallest int48 or
     * greater than largest int48).
     *
     * Counterpart to Solidity's `int48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     *
     * _Available since v4.7._
     */
    function toInt48(int256 value) internal pure returns (int48 downcasted) {
        downcasted = int48(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
    }

    /**
     * @dev Returns the downcasted int40 from int256, reverting on
     * overflow (when the input is less than smallest int40 or
     * greater than largest int40).
     *
     * Counterpart to Solidity's `int40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     *
     * _Available since v4.7._
     */
    function toInt40(int256 value) internal pure returns (int40 downcasted) {
        downcasted = int40(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32 downcasted) {
        downcasted = int32(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
    }

    /**
     * @dev Returns the downcasted int24 from int256, reverting on
     * overflow (when the input is less than smallest int24 or
     * greater than largest int24).
     *
     * Counterpart to Solidity's `int24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     *
     * _Available since v4.7._
     */
    function toInt24(int256 value) internal pure returns (int24 downcasted) {
        downcasted = int24(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16 downcasted) {
        downcasted = int16(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8 downcasted) {
        downcasted = int8(value);
        require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     *
     * _Available since v3.0._
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

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


// OpenZeppelin Contracts v4.4.1 (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/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.1) (utils/Checkpoints.sol)
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.

pragma solidity ^0.8.0;



/**
 * @dev This library defines the `History` struct, for checkpointing values as they change at different points in
 * time, and later looking up past values by block number. See {Votes} as an example.
 *
 * To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new
 * checkpoint for the current transaction block using the {push} function.
 *
 * _Available since v4.5._
 */
library Checkpoints {
    struct History {
        Checkpoint[] _checkpoints;
    }

    struct Checkpoint {
        uint32 _blockNumber;
        uint224 _value;
    }

    /**
     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
     * before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the
     * block, the requested block number must be in the past, excluding the current block.
     */
    function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
        require(blockNumber < block.number, "Checkpoints: block not yet mined");
        uint32 key = SafeCast.toUint32(blockNumber);

        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
     * before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched
     * checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of
     * checkpoints.
     */
    function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
        require(blockNumber < block.number, "Checkpoints: block not yet mined");
        uint32 key = SafeCast.toUint32(blockNumber);

        uint256 len = self._checkpoints.length;

        uint256 low = 0;
        uint256 high = len;

        if (len > 5) {
            uint256 mid = len - Math.sqrt(len);
            if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);

        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.
     *
     * Returns previous value and new value.
     */
    function push(History storage self, uint256 value) internal returns (uint256, uint256) {
        return _insert(self._checkpoints, SafeCast.toUint32(block.number), SafeCast.toUint224(value));
    }

    /**
     * @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will
     * be set to `op(latest, delta)`.
     *
     * Returns previous value and new value.
     */
    function push(
        History storage self,
        function(uint256, uint256) view returns (uint256) op,
        uint256 delta
    ) internal returns (uint256, uint256) {
        return push(self, op(latest(self), delta));
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(History storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(History storage self)
        internal
        view
        returns (
            bool exists,
            uint32 _blockNumber,
            uint224 _value
        )
    {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._blockNumber, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(History storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(
        Checkpoint[] storage self,
        uint32 key,
        uint224 value
    ) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint memory last = _unsafeAccess(self, pos - 1);

            // Checkpoints keys must be increasing.
            require(last._blockNumber <= key, "Checkpoint: invalid key");

            // Update or push new checkpoint
            if (last._blockNumber == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint({_blockNumber: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint({_blockNumber: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._blockNumber > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._blockNumber < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace224 {
        Checkpoint224[] _checkpoints;
    }

    struct Checkpoint224 {
        uint32 _key;
        uint224 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     */
    function push(
        Trace224 storage self,
        uint32 key,
        uint224 value
    ) internal returns (uint224, uint224) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none.
     */
    function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key.
     */
    function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace224 storage self) internal view returns (uint224) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace224 storage self)
        internal
        view
        returns (
            bool exists,
            uint32 _key,
            uint224 _value
        )
    {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace224 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(
        Checkpoint224[] storage self,
        uint32 key,
        uint224 value
    ) private returns (uint224, uint224) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint224 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoints keys must be increasing.
            require(last._key <= key, "Checkpoint: invalid key");

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint224({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint224({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint224[] storage self,
        uint32 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(Checkpoint224[] storage self, uint256 pos)
        private
        pure
        returns (Checkpoint224 storage result)
    {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }

    struct Trace160 {
        Checkpoint160[] _checkpoints;
    }

    struct Checkpoint160 {
        uint96 _key;
        uint160 _value;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.
     *
     * Returns previous value and new value.
     */
    function push(
        Trace160 storage self,
        uint96 key,
        uint160 value
    ) internal returns (uint160, uint160) {
        return _insert(self._checkpoints, key, value);
    }

    /**
     * @dev Returns the value in the oldest checkpoint with key greater or equal than the search key, or zero if there is none.
     */
    function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint with key lower or equal than the search key.
     */
    function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
        uint256 len = self._checkpoints.length;
        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
     */
    function latest(Trace160 storage self) internal view returns (uint160) {
        uint256 pos = self._checkpoints.length;
        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
    }

    /**
     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
     * in the most recent checkpoint.
     */
    function latestCheckpoint(Trace160 storage self)
        internal
        view
        returns (
            bool exists,
            uint96 _key,
            uint160 _value
        )
    {
        uint256 pos = self._checkpoints.length;
        if (pos == 0) {
            return (false, 0, 0);
        } else {
            Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
            return (true, ckpt._key, ckpt._value);
        }
    }

    /**
     * @dev Returns the number of checkpoint.
     */
    function length(Trace160 storage self) internal view returns (uint256) {
        return self._checkpoints.length;
    }

    /**
     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
     * or by updating the last one.
     */
    function _insert(
        Checkpoint160[] storage self,
        uint96 key,
        uint160 value
    ) private returns (uint160, uint160) {
        uint256 pos = self.length;

        if (pos > 0) {
            // Copying to memory is important here.
            Checkpoint160 memory last = _unsafeAccess(self, pos - 1);

            // Checkpoints keys must be increasing.
            require(last._key <= key, "Checkpoint: invalid key");

            // Update or push new checkpoint
            if (last._key == key) {
                _unsafeAccess(self, pos - 1)._value = value;
            } else {
                self.push(Checkpoint160({_key: key, _value: value}));
            }
            return (last._value, value);
        } else {
            self.push(Checkpoint160({_key: key, _value: value}));
            return (0, value);
        }
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _upperBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key > key) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return high;
    }

    /**
     * @dev Return the index of the oldest checkpoint whose key is greater or equal than the search key, or `high` if there is none.
     * `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
     *
     * WARNING: `high` should not be greater than the array's length.
     */
    function _lowerBinaryLookup(
        Checkpoint160[] storage self,
        uint96 key,
        uint256 low,
        uint256 high
    ) private view returns (uint256) {
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (_unsafeAccess(self, mid)._key < key) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        return high;
    }

    /**
     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
     */
    function _unsafeAccess(Checkpoint160[] storage self, uint256 pos)
        private
        pure
        returns (Checkpoint160 storage result)
    {
        assembly {
            mstore(0, self.slot)
            result.slot := add(keccak256(0, 0x20), pos)
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;


/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.0;


/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}

// File: @openzeppelin/contracts/utils/cryptography/draft-EIP712.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/draft-EIP712.sol)

pragma solidity ^0.8.0;

// EIP-712 is Final as of 2022-08-11. This file is deprecated.


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


// OpenZeppelin Contracts v4.4.1 (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/governance/utils/Votes.sol


// OpenZeppelin Contracts (last updated v4.8.0) (governance/utils/Votes.sol)
pragma solidity ^0.8.0;






/**
 * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be
 * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of
 * "representative" that will pool delegated voting units from different accounts and can then use it to vote in
 * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to
 * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative.
 *
 * This contract is often combined with a token contract such that voting units correspond to token units. For an
 * example, see {ERC721Votes}.
 *
 * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed
 * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the
 * cost of this history tracking optional.
 *
 * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return
 * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the
 * previous example, it would be included in {ERC721-_beforeTokenTransfer}).
 *
 * _Available since v4.5._
 */
abstract contract Votes is IVotes, Context, EIP712 {
    using Checkpoints for Checkpoints.History;
    using Counters for Counters.Counter;

    bytes32 private constant _DELEGATION_TYPEHASH =
        keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    mapping(address => address) private _delegation;
    mapping(address => Checkpoints.History) private _delegateCheckpoints;
    Checkpoints.History private _totalCheckpoints;

    mapping(address => Counters.Counter) private _nonces;

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) public view virtual override returns (uint256) {
        return _delegateCheckpoints[account].latest();
    }

    /**
     * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {
        return _delegateCheckpoints[account].getAtProbablyRecentBlock(blockNumber);
    }

    /**
     * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {
        require(blockNumber < block.number, "Votes: block not yet mined");
        return _totalCheckpoints.getAtProbablyRecentBlock(blockNumber);
    }

    /**
     * @dev Returns the current total supply of votes.
     */
    function _getTotalSupply() internal view virtual returns (uint256) {
        return _totalCheckpoints.latest();
    }

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) public view virtual override returns (address) {
        return _delegation[account];
    }

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) public virtual override {
        address account = _msgSender();
        _delegate(account, delegatee);
    }

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= expiry, "Votes: signature expired");
        address signer = ECDSA.recover(
            _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
            v,
            r,
            s
        );
        require(nonce == _useNonce(signer), "Votes: invalid nonce");
        _delegate(signer, delegatee);
    }

    /**
     * @dev Delegate all of `account`'s voting units to `delegatee`.
     *
     * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.
     */
    function _delegate(address account, address delegatee) internal virtual {
        address oldDelegate = delegates(account);
        _delegation[account] = delegatee;

        emit DelegateChanged(account, oldDelegate, delegatee);
        _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account));
    }

    /**
     * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to`
     * should be zero. Total supply of voting units will be adjusted with mints and burns.
     */
    function _transferVotingUnits(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        if (from == address(0)) {
            _totalCheckpoints.push(_add, amount);
        }
        if (to == address(0)) {
            _totalCheckpoints.push(_subtract, amount);
        }
        _moveDelegateVotes(delegates(from), delegates(to), amount);
    }

    /**
     * @dev Moves delegated votes from one delegate to another.
     */
    function _moveDelegateVotes(
        address from,
        address to,
        uint256 amount
    ) private {
        if (from != to && amount > 0) {
            if (from != address(0)) {
                (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[from].push(_subtract, amount);
                emit DelegateVotesChanged(from, oldValue, newValue);
            }
            if (to != address(0)) {
                (uint256 oldValue, uint256 newValue) = _delegateCheckpoints[to].push(_add, amount);
                emit DelegateVotesChanged(to, oldValue, newValue);
            }
        }
    }

    function _add(uint256 a, uint256 b) private pure returns (uint256) {
        return a + b;
    }

    function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Consumes a nonce.
     *
     * Returns the current value and increments nonce.
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }

    /**
     * @dev Returns an address nonce.
     */
    function nonces(address owner) public view virtual returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev Returns the contract's {EIP712} domain separator.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev Must return the voting units held by an account.
     */
    function _getVotingUnits(address) internal view virtual returns (uint256);
}

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


// OpenZeppelin Contracts (last updated v4.7.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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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 (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-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 (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

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


// OpenZeppelin Contracts v4.4.1 (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.1 (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 (last updated v4.8.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`.
     *
     * 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;

    /**
     * @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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @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);
}

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


// OpenZeppelin Contracts v4.4.1 (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 (last updated v4.8.2) (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: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        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) {
        _requireMinted(tokenId);

        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 overridden 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 token owner or approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        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: caller is not token owner or 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: caller is not token owner or 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 the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @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 _ownerOf(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) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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, 1);

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

    /**
     * @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 from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {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 an {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 Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @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 {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
     * that `ownerOf(tokenId)` is `a`.
     */
    // solhint-disable-next-line func-name-mixedcase
    function __unsafe_increaseBalance(address account, uint256 amount) internal {
        _balances[account] += amount;
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Votes.sol)

pragma solidity ^0.8.0;



/**
 * @dev Extension of ERC721 to support voting and delegation as implemented by {Votes}, where each individual NFT counts
 * as 1 vote unit.
 *
 * Tokens do not count as votes until they are delegated, because votes must be tracked which incurs an additional cost
 * on every transfer. Token holders can either delegate to a trusted representative who will decide how to make use of
 * the votes in governance decisions, or they can delegate to themselves to be their own representative.
 *
 * _Available since v4.5._
 */
abstract contract ERC721Votes is ERC721, Votes {
    /**
     * @dev See {ERC721-_afterTokenTransfer}. Adjusts votes when tokens are transferred.
     *
     * Emits a {IVotes-DelegateVotesChanged} event.
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        _transferVotingUnits(from, to, batchSize);
        super._afterTokenTransfer(from, to, firstTokenId, batchSize);
    }

    /**
     * @dev Returns the balance of `account`.
     */
    function _getVotingUnits(address account) internal view virtual override returns (uint256) {
        return balanceOf(account);
    }
}

// File: @openzeppelin/contracts/token/ERC721/extensions/draft-ERC721Votes.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/draft-ERC721Votes.sol)

pragma solidity ^0.8.0;

// ERC721Votes was marked as draft due to the EIP-712 dependency.
// EIP-712 is Final as of 2022-08-11. This file is deprecated.


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


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Burnable.sol)

pragma solidity ^0.8.0;



/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be 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), "ERC721: caller is not token owner or approved");
        _burn(tokenId);
    }
}

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


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)

pragma solidity ^0.8.0;


/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev See {ERC721-_burn}. This override additionally checks to see if a
     * token-specific URI was set for the token, and if so, it deletes the token URI from
     * the storage mapping.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

// File: Crazy Owl.sol


pragma solidity ^0.8.9;








contract CrazyOwl is ERC721, ERC721URIStorage, ERC721Burnable, Ownable, EIP712, ERC721Votes {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("Crazy Owl", "COWL") EIP712("Crazy Owl", "1") {}

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _afterTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
        internal
        override(ERC721, ERC721Votes)
    {
        super._afterTokenTransfer(from, to, tokenId, batchSize);
    }

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"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":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"uri","type":"string"}],"name":"safeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"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":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101406040523480156200001257600080fd5b506040518060400160405280600981526020017f4372617a79204f776c00000000000000000000000000000000000000000000008152506040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506040518060400160405280600981526020017f4372617a79204f776c00000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f434f574c000000000000000000000000000000000000000000000000000000008152508160009081620000fc91906200056d565b5080600190816200010e91906200056d565b5050506200013162000125620001e960201b60201c565b620001f160201b60201c565b60008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508260e081815250508161010081815250504660a081815250506200019a818484620002b760201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1681525050806101208181525050505050505062000722565b600033905090565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008383834630604051602001620002d4959493929190620006c5565b6040516020818303038152906040528051906020012090509392505050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200037557607f821691505b6020821081036200038b576200038a6200032d565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003f57fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003b6565b620004018683620003b6565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200044e62000448620004428462000419565b62000423565b62000419565b9050919050565b6000819050919050565b6200046a836200042d565b62000482620004798262000455565b848454620003c3565b825550505050565b600090565b620004996200048a565b620004a68184846200045f565b505050565b5b81811015620004ce57620004c26000826200048f565b600181019050620004ac565b5050565b601f8211156200051d57620004e78162000391565b620004f284620003a6565b8101602085101562000502578190505b6200051a6200051185620003a6565b830182620004ab565b50505b505050565b600082821c905092915050565b6000620005426000198460080262000522565b1980831691505092915050565b60006200055d83836200052f565b9150826002028217905092915050565b6200057882620002f3565b67ffffffffffffffff811115620005945762000593620002fe565b5b620005a082546200035c565b620005ad828285620004d2565b600060209050601f831160018114620005e55760008415620005d0578287015190505b620005dc85826200054f565b8655506200064c565b601f198416620005f58662000391565b60005b828110156200061f57848901518255600182019150602085019450602081019050620005f8565b868310156200063f57848901516200063b601f8916826200052f565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b620006698162000654565b82525050565b6200067a8162000419565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620006ad8262000680565b9050919050565b620006bf81620006a0565b82525050565b600060a082019050620006dc60008301886200065e565b620006eb60208301876200065e565b620006fa60408301866200065e565b6200070960608301856200066f565b620007186080830184620006b4565b9695505050505050565b60805160a05160c05160e051610100516101205161502d620007726000396000611591015260006115d3015260006115b2015260006114e70152600061153d01526000611566015261502d6000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c8063715018a6116100de578063a22cb46511610097578063c87b56dd11610071578063c87b56dd146104a5578063d204c45e146104d5578063e985e9c5146104f1578063f2fde38b146105215761018e565b8063a22cb46514610451578063b88d4fde1461046d578063c3cda520146104895761018e565b8063715018a61461037b5780637ecebe00146103855780638da5cb5b146103b55780638e539e8c146103d357806395d89b41146104035780639ab24eb0146104215761018e565b80633a46b1a81161014b578063587cde1e11610125578063587cde1e146102cf5780635c19a95c146102ff5780636352211e1461031b57806370a082311461034b5761018e565b80633a46b1a81461026757806342842e0e1461029757806342966c68146102b35761018e565b806301ffc9a71461019357806306fdde03146101c3578063081812fc146101e1578063095ea7b31461021157806323b872dd1461022d5780633644e51514610249575b600080fd5b6101ad60048036038101906101a8919061359e565b61053d565b6040516101ba91906135e6565b60405180910390f35b6101cb61061f565b6040516101d89190613691565b60405180910390f35b6101fb60048036038101906101f691906136e9565b6106b1565b6040516102089190613757565b60405180910390f35b61022b6004803603810190610226919061379e565b6106f7565b005b610247600480360381019061024291906137de565b61080e565b005b61025161086e565b60405161025e919061384a565b60405180910390f35b610281600480360381019061027c919061379e565b61087d565b60405161028e9190613874565b60405180910390f35b6102b160048036038101906102ac91906137de565b6108d8565b005b6102cd60048036038101906102c891906136e9565b6108f8565b005b6102e960048036038101906102e4919061388f565b610954565b6040516102f69190613757565b60405180910390f35b6103196004803603810190610314919061388f565b6109bd565b005b610335600480360381019061033091906136e9565b6109d7565b6040516103429190613757565b60405180910390f35b6103656004803603810190610360919061388f565b610a5d565b6040516103729190613874565b60405180910390f35b610383610b14565b005b61039f600480360381019061039a919061388f565b610b28565b6040516103ac9190613874565b60405180910390f35b6103bd610b78565b6040516103ca9190613757565b60405180910390f35b6103ed60048036038101906103e891906136e9565b610ba2565b6040516103fa9190613874565b60405180910390f35b61040b610c01565b6040516104189190613691565b60405180910390f35b61043b6004803603810190610436919061388f565b610c93565b6040516104489190613874565b60405180910390f35b61046b600480360381019061046691906138e8565b610d01565b005b61048760048036038101906104829190613a5d565b610d17565b005b6104a3600480360381019061049e9190613b45565b610d79565b005b6104bf60048036038101906104ba91906136e9565b610e7d565b6040516104cc9190613691565b60405180910390f35b6104ef60048036038101906104ea9190613c73565b610e8f565b005b61050b60048036038101906105069190613ccf565b610ec8565b60405161051891906135e6565b60405180910390f35b61053b6004803603810190610536919061388f565b610f5c565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061060857507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610618575061061782610fdf565b5b9050919050565b60606000805461062e90613d3e565b80601f016020809104026020016040519081016040528092919081815260200182805461065a90613d3e565b80156106a75780601f1061067c576101008083540402835291602001916106a7565b820191906000526020600020905b81548152906001019060200180831161068a57829003601f168201915b5050505050905090565b60006106bc82611049565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610702826109d7565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610772576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076990613de1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610791611094565b73ffffffffffffffffffffffffffffffffffffffff1614806107c057506107bf816107ba611094565b610ec8565b5b6107ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f690613e73565b60405180910390fd5b610809838361109c565b505050565b61081f610819611094565b82611155565b61085e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085590613f05565b60405180910390fd5b6108698383836111ea565b505050565b60006108786114e3565b905090565b60006108d082600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206115fd90919063ffffffff16565b905092915050565b6108f383838360405180602001604052806000815250610d17565b505050565b610909610903611094565b82611155565b610948576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093f90613f05565b60405180910390fd5b61095181611762565b50565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109c7611094565b90506109d3818361176e565b5050565b6000806109e383611882565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4b90613f71565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac490614003565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610b1c6118bf565b610b26600061193d565b565b6000610b71600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a03565b9050919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000438210610be6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdd9061406f565b60405180910390fd5b610bfa82600a6115fd90919063ffffffff16565b9050919050565b606060018054610c1090613d3e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3c90613d3e565b8015610c895780601f10610c5e57610100808354040283529160200191610c89565b820191906000526020600020905b815481529060010190602001808311610c6c57829003601f168201915b5050505050905090565b6000610cdc600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a11565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169050919050565b610d13610d0c611094565b8383611a7b565b5050565b610d28610d22611094565b83611155565b610d67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5e90613f05565b60405180910390fd5b610d7384848484611be7565b50505050565b83421115610dbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db3906140db565b60405180910390fd5b6000610e1e610e167fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf898989604051602001610dfb94939291906140fb565b60405160208183030381529060405280519060200120611c43565b858585611c5d565b9050610e2981611c88565b8614610e6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e619061418c565b60405180910390fd5b610e74818861176e565b50505050505050565b6060610e8882611ce6565b9050919050565b610e976118bf565b6000610ea3600c611a03565b9050610eaf600c611df8565b610eb98382611e0e565b610ec38183611e2c565b505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610f646118bf565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca9061421e565b60405180910390fd5b610fdc8161193d565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61105281611e99565b611091576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108890613f71565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661110f836109d7565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080611161836109d7565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806111a357506111a28185610ec8565b5b806111e157508373ffffffffffffffffffffffffffffffffffffffff166111c9846106b1565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661120a826109d7565b73ffffffffffffffffffffffffffffffffffffffff1614611260576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611257906142b0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c690614342565b60405180910390fd5b6112dc8383836001611eda565b8273ffffffffffffffffffffffffffffffffffffffff166112fc826109d7565b73ffffffffffffffffffffffffffffffffffffffff1614611352576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611349906142b0565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46114de8383836001611ee0565b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561155f57507f000000000000000000000000000000000000000000000000000000000000000046145b1561158c577f000000000000000000000000000000000000000000000000000000000000000090506115fa565b6115f77f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000611ef2565b90505b90565b6000438210611641576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611638906143ae565b60405180910390fd5b600061164c83611f2c565b905060008460000180549050905060008082905060058311156116cf57600061167484611f7f565b8461167f91906143fd565b905061168e8860000182612078565b60000160009054906101000a900463ffffffff1663ffffffff168563ffffffff1610156116bd578091506116cd565b6001816116ca9190614431565b92505b505b60006116e08860000186858561208d565b90506000811461173457611703886000016001836116fe91906143fd565b612078565b60000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611737565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169550505050505092915050565b61176b81612100565b50565b600061177983610954565b905081600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a461187d818361187886612153565b612165565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6118c7611094565b73ffffffffffffffffffffffffffffffffffffffff166118e5610b78565b73ffffffffffffffffffffffffffffffffffffffff161461193b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611932906144b1565b60405180910390fd5b565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081600001549050919050565b6000808260000180549050905060008114611a7057611a3f83600001600183611a3a91906143fd565b612078565b60000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611a73565b60005b915050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611ae9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae09061451d565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611bda91906135e6565b60405180910390a3505050565b611bf28484846111ea565b611bfe84848484612372565b611c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c34906145af565b60405180910390fd5b50505050565b6000611c56611c506114e3565b836124f9565b9050919050565b6000806000611c6e8787878761252c565b91509150611c7b8161260e565b8192505050949350505050565b600080600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611cd581611a03565b9150611ce081611df8565b50919050565b6060611cf182611049565b6000600660008481526020019081526020016000208054611d1190613d3e565b80601f0160208091040260200160405190810160405280929190818152602001828054611d3d90613d3e565b8015611d8a5780601f10611d5f57610100808354040283529160200191611d8a565b820191906000526020600020905b815481529060010190602001808311611d6d57829003601f168201915b505050505090506000611d9b612774565b90506000815103611db0578192505050611df3565b600082511115611de5578082604051602001611dcd92919061460b565b60405160208183030381529060405292505050611df3565b611dee8461278b565b925050505b919050565b6001816000016000828254019250508190555050565b611e288282604051806020016040528060008152506127f3565b5050565b611e3582611e99565b611e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6b906146a1565b60405180910390fd5b80600660008481526020019081526020016000209081611e94919061486d565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff16611ebb83611882565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b50505050565b611eec8484848461284e565b50505050565b60008383834630604051602001611f0d95949392919061493f565b6040516020818303038152906040528051906020012090509392505050565b600063ffffffff8016821115611f77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6e90614a04565b60405180910390fd5b819050919050565b6000808203611f915760009050612073565b60006001611f9e8461286b565b901c6001901b90506001818481611fb857611fb7614a24565b5b048201901c90506001818481611fd157611fd0614a24565b5b048201901c90506001818481611fea57611fe9614a24565b5b048201901c9050600181848161200357612002614a24565b5b048201901c9050600181848161201c5761201b614a24565b5b048201901c9050600181848161203557612034614a24565b5b048201901c9050600181848161204e5761204d614a24565b5b048201901c905061206f8182858161206957612068614a24565b5b0461294c565b9150505b919050565b60008260005281602060002001905092915050565b60005b818310156120f55760006120a48484612965565b90508463ffffffff166120b78783612078565b60000160009054906101000a900463ffffffff1663ffffffff1611156120df578092506120ef565b6001816120ec9190614431565b93505b50612090565b819050949350505050565b6121098161298b565b600060066000838152602001908152602001600020805461212990613d3e565b9050146121505760066000828152602001908152602001600020600061214f91906134d5565b5b50565b600061215e82610a5d565b9050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156121a15750600081115b1561236d57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461228957600080612232612ad984600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612aef9092919063ffffffff16565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161227e929190614a53565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461236c57600080612315612b3b84600960008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612aef9092919063ffffffff16565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612361929190614a53565b60405180910390a250505b5b505050565b60006123938473ffffffffffffffffffffffffffffffffffffffff16612b51565b156124ec578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026123bc611094565b8786866040518563ffffffff1660e01b81526004016123de9493929190614ad1565b6020604051808303816000875af192505050801561241a57506040513d601f19601f820116820180604052508101906124179190614b32565b60015b61249c573d806000811461244a576040519150601f19603f3d011682016040523d82523d6000602084013e61244f565b606091505b506000815103612494576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248b906145af565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506124f1565b600190505b949350505050565b6000828260405160200161250e929190614bcc565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612567576000600391509150612605565b60006001878787876040516000815260200160405260405161258c9493929190614c12565b6020604051602081039080840390855afa1580156125ae573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036125fc57600060019250925050612605565b80600092509250505b94509492505050565b6000600481111561262257612621614c57565b5b81600481111561263557612634614c57565b5b0315612771576001600481111561264f5761264e614c57565b5b81600481111561266257612661614c57565b5b036126a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161269990614cd2565b60405180910390fd5b600260048111156126b6576126b5614c57565b5b8160048111156126c9576126c8614c57565b5b03612709576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270090614d3e565b60405180910390fd5b6003600481111561271d5761271c614c57565b5b8160048111156127305761272f614c57565b5b03612770576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161276790614dd0565b60405180910390fd5b5b50565b606060405180602001604052806000815250905090565b606061279682611049565b60006127a0612774565b905060008151116127c057604051806020016040528060008152506127eb565b806127ca84612b74565b6040516020016127db92919061460b565b6040516020818303038152906040525b915050919050565b6127fd8383612c42565b61280a6000848484612372565b612849576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612840906145af565b60405180910390fd5b505050565b612859848483612e5f565b61286584848484612f1d565b50505050565b600080600090506000608084901c111561288d57608083901c92506080810190505b6000604084901c11156128a857604083901c92506040810190505b6000602084901c11156128c357602083901c92506020810190505b6000601084901c11156128de57601083901c92506010810190505b6000600884901c11156128f957600883901c92506008810190505b6000600484901c111561291457600483901c92506004810190505b6000600284901c111561292f57600283901c92506002810190505b6000600184901c1115612943576001810190505b80915050919050565b600081831061295b578161295d565b825b905092915050565b600060028284186129769190614df0565b8284166129839190614431565b905092915050565b6000612996826109d7565b90506129a6816000846001611eda565b6129af826109d7565b90506004600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ad5816000846001611ee0565b5050565b60008183612ae791906143fd565b905092915050565b600080612b2f85612b2a612b0288611a11565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16868863ffffffff16565b612f23565b91509150935093915050565b60008183612b499190614431565b905092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606060006001612b8384612f91565b01905060008167ffffffffffffffff811115612ba257612ba1613932565b5b6040519080825280601f01601f191660200182016040528015612bd45781602001600182028036833780820191505090505b509050600082602001820190505b600115612c37578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612c2b57612c2a614a24565b5b04945060008503612be2575b819350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612cb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca890614e6d565b60405180910390fd5b612cba81611e99565b15612cfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cf190614ed9565b60405180910390fd5b612d08600083836001611eda565b612d1181611e99565b15612d51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4890614ed9565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612e5b600083836001611ee0565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612eae57612eab612b3b82600a612aef9092919063ffffffff16565b50505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612efd57612efa612ad982600a612aef9092919063ffffffff16565b50505b612f18612f0984610954565b612f1284610954565b83612165565b505050565b50505050565b600080612f4484600001612f3643611f2c565b612f3f866130e4565b61314f565b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169150807bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169050915091509250929050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612fef577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612fe557612fe4614a24565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061302c576d04ee2d6d415b85acef8100000000838161302257613021614a24565b5b0492506020810190505b662386f26fc10000831061305b57662386f26fc10000838161305157613050614a24565b5b0492506010810190505b6305f5e1008310613084576305f5e100838161307a57613079614a24565b5b0492506008810190505b61271083106130a957612710838161309f5761309e614a24565b5b0492506004810190505b606483106130cc57606483816130c2576130c1614a24565b5b0492506002810190505b600a83106130db576001810190505b80915050919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115613147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313e90614f6b565b60405180910390fd5b819050919050565b60008060008580549050905060008111156133e557600061317c8760018461317791906143fd565b612078565b6040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508563ffffffff16816000015163ffffffff161115613270576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326790614fd7565b60405180910390fd5b8563ffffffff16816000015163ffffffff16036132f4578461329e8860018561329991906143fd565b612078565b60000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055506133d4565b8660405180604001604052808863ffffffff168152602001877bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b8060200151859350935050506134cd565b8560405180604001604052808763ffffffff168152602001867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505060008492509250505b935093915050565b5080546134e190613d3e565b6000825580601f106134f35750613512565b601f0160209004906000526020600020908101906135119190613515565b5b50565b5b8082111561352e576000816000905550600101613516565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61357b81613546565b811461358657600080fd5b50565b60008135905061359881613572565b92915050565b6000602082840312156135b4576135b361353c565b5b60006135c284828501613589565b91505092915050565b60008115159050919050565b6135e0816135cb565b82525050565b60006020820190506135fb60008301846135d7565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561363b578082015181840152602081019050613620565b60008484015250505050565b6000601f19601f8301169050919050565b600061366382613601565b61366d818561360c565b935061367d81856020860161361d565b61368681613647565b840191505092915050565b600060208201905081810360008301526136ab8184613658565b905092915050565b6000819050919050565b6136c6816136b3565b81146136d157600080fd5b50565b6000813590506136e3816136bd565b92915050565b6000602082840312156136ff576136fe61353c565b5b600061370d848285016136d4565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061374182613716565b9050919050565b61375181613736565b82525050565b600060208201905061376c6000830184613748565b92915050565b61377b81613736565b811461378657600080fd5b50565b60008135905061379881613772565b92915050565b600080604083850312156137b5576137b461353c565b5b60006137c385828601613789565b92505060206137d4858286016136d4565b9150509250929050565b6000806000606084860312156137f7576137f661353c565b5b600061380586828701613789565b935050602061381686828701613789565b9250506040613827868287016136d4565b9150509250925092565b6000819050919050565b61384481613831565b82525050565b600060208201905061385f600083018461383b565b92915050565b61386e816136b3565b82525050565b60006020820190506138896000830184613865565b92915050565b6000602082840312156138a5576138a461353c565b5b60006138b384828501613789565b91505092915050565b6138c5816135cb565b81146138d057600080fd5b50565b6000813590506138e2816138bc565b92915050565b600080604083850312156138ff576138fe61353c565b5b600061390d85828601613789565b925050602061391e858286016138d3565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61396a82613647565b810181811067ffffffffffffffff8211171561398957613988613932565b5b80604052505050565b600061399c613532565b90506139a88282613961565b919050565b600067ffffffffffffffff8211156139c8576139c7613932565b5b6139d182613647565b9050602081019050919050565b82818337600083830152505050565b6000613a006139fb846139ad565b613992565b905082815260208101848484011115613a1c57613a1b61392d565b5b613a278482856139de565b509392505050565b600082601f830112613a4457613a43613928565b5b8135613a548482602086016139ed565b91505092915050565b60008060008060808587031215613a7757613a7661353c565b5b6000613a8587828801613789565b9450506020613a9687828801613789565b9350506040613aa7878288016136d4565b925050606085013567ffffffffffffffff811115613ac857613ac7613541565b5b613ad487828801613a2f565b91505092959194509250565b600060ff82169050919050565b613af681613ae0565b8114613b0157600080fd5b50565b600081359050613b1381613aed565b92915050565b613b2281613831565b8114613b2d57600080fd5b50565b600081359050613b3f81613b19565b92915050565b60008060008060008060c08789031215613b6257613b6161353c565b5b6000613b7089828a01613789565b9650506020613b8189828a016136d4565b9550506040613b9289828a016136d4565b9450506060613ba389828a01613b04565b9350506080613bb489828a01613b30565b92505060a0613bc589828a01613b30565b9150509295509295509295565b600067ffffffffffffffff821115613bed57613bec613932565b5b613bf682613647565b9050602081019050919050565b6000613c16613c1184613bd2565b613992565b905082815260208101848484011115613c3257613c3161392d565b5b613c3d8482856139de565b509392505050565b600082601f830112613c5a57613c59613928565b5b8135613c6a848260208601613c03565b91505092915050565b60008060408385031215613c8a57613c8961353c565b5b6000613c9885828601613789565b925050602083013567ffffffffffffffff811115613cb957613cb8613541565b5b613cc585828601613c45565b9150509250929050565b60008060408385031215613ce657613ce561353c565b5b6000613cf485828601613789565b9250506020613d0585828601613789565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613d5657607f821691505b602082108103613d6957613d68613d0f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000613dcb60218361360c565b9150613dd682613d6f565b604082019050919050565b60006020820190508181036000830152613dfa81613dbe565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000613e5d603d8361360c565b9150613e6882613e01565b604082019050919050565b60006020820190508181036000830152613e8c81613e50565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613eef602d8361360c565b9150613efa82613e93565b604082019050919050565b60006020820190508181036000830152613f1e81613ee2565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613f5b60188361360c565b9150613f6682613f25565b602082019050919050565b60006020820190508181036000830152613f8a81613f4e565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613fed60298361360c565b9150613ff882613f91565b604082019050919050565b6000602082019050818103600083015261401c81613fe0565b9050919050565b7f566f7465733a20626c6f636b206e6f7420796574206d696e6564000000000000600082015250565b6000614059601a8361360c565b915061406482614023565b602082019050919050565b600060208201905081810360008301526140888161404c565b9050919050565b7f566f7465733a207369676e617475726520657870697265640000000000000000600082015250565b60006140c560188361360c565b91506140d08261408f565b602082019050919050565b600060208201905081810360008301526140f4816140b8565b9050919050565b6000608082019050614110600083018761383b565b61411d6020830186613748565b61412a6040830185613865565b6141376060830184613865565b95945050505050565b7f566f7465733a20696e76616c6964206e6f6e6365000000000000000000000000600082015250565b600061417660148361360c565b915061418182614140565b602082019050919050565b600060208201905081810360008301526141a581614169565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061420860268361360c565b9150614213826141ac565b604082019050919050565b60006020820190508181036000830152614237816141fb565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061429a60258361360c565b91506142a58261423e565b604082019050919050565b600060208201905081810360008301526142c98161428d565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061432c60248361360c565b9150614337826142d0565b604082019050919050565b6000602082019050818103600083015261435b8161431f565b9050919050565b7f436865636b706f696e74733a20626c6f636b206e6f7420796574206d696e6564600082015250565b600061439860208361360c565b91506143a382614362565b602082019050919050565b600060208201905081810360008301526143c78161438b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614408826136b3565b9150614413836136b3565b925082820390508181111561442b5761442a6143ce565b5b92915050565b600061443c826136b3565b9150614447836136b3565b925082820190508082111561445f5761445e6143ce565b5b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061449b60208361360c565b91506144a682614465565b602082019050919050565b600060208201905081810360008301526144ca8161448e565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061450760198361360c565b9150614512826144d1565b602082019050919050565b60006020820190508181036000830152614536816144fa565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b600061459960328361360c565b91506145a48261453d565b604082019050919050565b600060208201905081810360008301526145c88161458c565b9050919050565b600081905092915050565b60006145e582613601565b6145ef81856145cf565b93506145ff81856020860161361d565b80840191505092915050565b600061461782856145da565b915061462382846145da565b91508190509392505050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b600061468b602e8361360c565b91506146968261462f565b604082019050919050565b600060208201905081810360008301526146ba8161467e565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026147237fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826146e6565b61472d86836146e6565b95508019841693508086168417925050509392505050565b6000819050919050565b600061476a614765614760846136b3565b614745565b6136b3565b9050919050565b6000819050919050565b6147848361474f565b61479861479082614771565b8484546146f3565b825550505050565b600090565b6147ad6147a0565b6147b881848461477b565b505050565b5b818110156147dc576147d16000826147a5565b6001810190506147be565b5050565b601f821115614821576147f2816146c1565b6147fb846146d6565b8101602085101561480a578190505b61481e614816856146d6565b8301826147bd565b50505b505050565b600082821c905092915050565b600061484460001984600802614826565b1980831691505092915050565b600061485d8383614833565b9150826002028217905092915050565b61487682613601565b67ffffffffffffffff81111561488f5761488e613932565b5b6148998254613d3e565b6148a48282856147e0565b600060209050601f8311600181146148d757600084156148c5578287015190505b6148cf8582614851565b865550614937565b601f1984166148e5866146c1565b60005b8281101561490d578489015182556001820191506020850194506020810190506148e8565b8683101561492a5784890151614926601f891682614833565b8355505b6001600288020188555050505b505050505050565b600060a082019050614954600083018861383b565b614961602083018761383b565b61496e604083018661383b565b61497b6060830185613865565b6149886080830184613748565b9695505050505050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b60006149ee60268361360c565b91506149f982614992565b604082019050919050565b60006020820190508181036000830152614a1d816149e1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000604082019050614a686000830185613865565b614a756020830184613865565b9392505050565b600081519050919050565b600082825260208201905092915050565b6000614aa382614a7c565b614aad8185614a87565b9350614abd81856020860161361d565b614ac681613647565b840191505092915050565b6000608082019050614ae66000830187613748565b614af36020830186613748565b614b006040830185613865565b8181036060830152614b128184614a98565b905095945050505050565b600081519050614b2c81613572565b92915050565b600060208284031215614b4857614b4761353c565b5b6000614b5684828501614b1d565b91505092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000614b956002836145cf565b9150614ba082614b5f565b600282019050919050565b6000819050919050565b614bc6614bc182613831565b614bab565b82525050565b6000614bd782614b88565b9150614be38285614bb5565b602082019150614bf38284614bb5565b6020820191508190509392505050565b614c0c81613ae0565b82525050565b6000608082019050614c27600083018761383b565b614c346020830186614c03565b614c41604083018561383b565b614c4e606083018461383b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000614cbc60188361360c565b9150614cc782614c86565b602082019050919050565b60006020820190508181036000830152614ceb81614caf565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614d28601f8361360c565b9150614d3382614cf2565b602082019050919050565b60006020820190508181036000830152614d5781614d1b565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614dba60228361360c565b9150614dc582614d5e565b604082019050919050565b60006020820190508181036000830152614de981614dad565b9050919050565b6000614dfb826136b3565b9150614e06836136b3565b925082614e1657614e15614a24565b5b828204905092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614e5760208361360c565b9150614e6282614e21565b602082019050919050565b60006020820190508181036000830152614e8681614e4a565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614ec3601c8361360c565b9150614ece82614e8d565b602082019050919050565b60006020820190508181036000830152614ef281614eb6565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b6000614f5560278361360c565b9150614f6082614ef9565b604082019050919050565b60006020820190508181036000830152614f8481614f48565b9050919050565b7f436865636b706f696e743a20696e76616c6964206b6579000000000000000000600082015250565b6000614fc160178361360c565b9150614fcc82614f8b565b602082019050919050565b60006020820190508181036000830152614ff081614fb4565b905091905056fea26469706673582212201ab0472614a8e981c825c09616f09840d3907562d4cb1b2e55504baf1ee5b24164736f6c63430008130033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063715018a6116100de578063a22cb46511610097578063c87b56dd11610071578063c87b56dd146104a5578063d204c45e146104d5578063e985e9c5146104f1578063f2fde38b146105215761018e565b8063a22cb46514610451578063b88d4fde1461046d578063c3cda520146104895761018e565b8063715018a61461037b5780637ecebe00146103855780638da5cb5b146103b55780638e539e8c146103d357806395d89b41146104035780639ab24eb0146104215761018e565b80633a46b1a81161014b578063587cde1e11610125578063587cde1e146102cf5780635c19a95c146102ff5780636352211e1461031b57806370a082311461034b5761018e565b80633a46b1a81461026757806342842e0e1461029757806342966c68146102b35761018e565b806301ffc9a71461019357806306fdde03146101c3578063081812fc146101e1578063095ea7b31461021157806323b872dd1461022d5780633644e51514610249575b600080fd5b6101ad60048036038101906101a8919061359e565b61053d565b6040516101ba91906135e6565b60405180910390f35b6101cb61061f565b6040516101d89190613691565b60405180910390f35b6101fb60048036038101906101f691906136e9565b6106b1565b6040516102089190613757565b60405180910390f35b61022b6004803603810190610226919061379e565b6106f7565b005b610247600480360381019061024291906137de565b61080e565b005b61025161086e565b60405161025e919061384a565b60405180910390f35b610281600480360381019061027c919061379e565b61087d565b60405161028e9190613874565b60405180910390f35b6102b160048036038101906102ac91906137de565b6108d8565b005b6102cd60048036038101906102c891906136e9565b6108f8565b005b6102e960048036038101906102e4919061388f565b610954565b6040516102f69190613757565b60405180910390f35b6103196004803603810190610314919061388f565b6109bd565b005b610335600480360381019061033091906136e9565b6109d7565b6040516103429190613757565b60405180910390f35b6103656004803603810190610360919061388f565b610a5d565b6040516103729190613874565b60405180910390f35b610383610b14565b005b61039f600480360381019061039a919061388f565b610b28565b6040516103ac9190613874565b60405180910390f35b6103bd610b78565b6040516103ca9190613757565b60405180910390f35b6103ed60048036038101906103e891906136e9565b610ba2565b6040516103fa9190613874565b60405180910390f35b61040b610c01565b6040516104189190613691565b60405180910390f35b61043b6004803603810190610436919061388f565b610c93565b6040516104489190613874565b60405180910390f35b61046b600480360381019061046691906138e8565b610d01565b005b61048760048036038101906104829190613a5d565b610d17565b005b6104a3600480360381019061049e9190613b45565b610d79565b005b6104bf60048036038101906104ba91906136e9565b610e7d565b6040516104cc9190613691565b60405180910390f35b6104ef60048036038101906104ea9190613c73565b610e8f565b005b61050b60048036038101906105069190613ccf565b610ec8565b60405161051891906135e6565b60405180910390f35b61053b6004803603810190610536919061388f565b610f5c565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061060857507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610618575061061782610fdf565b5b9050919050565b60606000805461062e90613d3e565b80601f016020809104026020016040519081016040528092919081815260200182805461065a90613d3e565b80156106a75780601f1061067c576101008083540402835291602001916106a7565b820191906000526020600020905b81548152906001019060200180831161068a57829003601f168201915b5050505050905090565b60006106bc82611049565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610702826109d7565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610772576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076990613de1565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610791611094565b73ffffffffffffffffffffffffffffffffffffffff1614806107c057506107bf816107ba611094565b610ec8565b5b6107ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f690613e73565b60405180910390fd5b610809838361109c565b505050565b61081f610819611094565b82611155565b61085e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085590613f05565b60405180910390fd5b6108698383836111ea565b505050565b60006108786114e3565b905090565b60006108d082600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206115fd90919063ffffffff16565b905092915050565b6108f383838360405180602001604052806000815250610d17565b505050565b610909610903611094565b82611155565b610948576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093f90613f05565b60405180910390fd5b61095181611762565b50565b6000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006109c7611094565b90506109d3818361176e565b5050565b6000806109e383611882565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610a54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4b90613f71565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ac490614003565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610b1c6118bf565b610b26600061193d565b565b6000610b71600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a03565b9050919050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000438210610be6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdd9061406f565b60405180910390fd5b610bfa82600a6115fd90919063ffffffff16565b9050919050565b606060018054610c1090613d3e565b80601f0160208091040260200160405190810160405280929190818152602001828054610c3c90613d3e565b8015610c895780601f10610c5e57610100808354040283529160200191610c89565b820191906000526020600020905b815481529060010190602001808311610c6c57829003601f168201915b5050505050905090565b6000610cdc600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a11565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169050919050565b610d13610d0c611094565b8383611a7b565b5050565b610d28610d22611094565b83611155565b610d67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5e90613f05565b60405180910390fd5b610d7384848484611be7565b50505050565b83421115610dbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db3906140db565b60405180910390fd5b6000610e1e610e167fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf898989604051602001610dfb94939291906140fb565b60405160208183030381529060405280519060200120611c43565b858585611c5d565b9050610e2981611c88565b8614610e6a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e619061418c565b60405180910390fd5b610e74818861176e565b50505050505050565b6060610e8882611ce6565b9050919050565b610e976118bf565b6000610ea3600c611a03565b9050610eaf600c611df8565b610eb98382611e0e565b610ec38183611e2c565b505050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b610f646118bf565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca9061421e565b60405180910390fd5b610fdc8161193d565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61105281611e99565b611091576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108890613f71565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661110f836109d7565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080611161836109d7565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806111a357506111a28185610ec8565b5b806111e157508373ffffffffffffffffffffffffffffffffffffffff166111c9846106b1565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661120a826109d7565b73ffffffffffffffffffffffffffffffffffffffff1614611260576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611257906142b0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c690614342565b60405180910390fd5b6112dc8383836001611eda565b8273ffffffffffffffffffffffffffffffffffffffff166112fc826109d7565b73ffffffffffffffffffffffffffffffffffffffff1614611352576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611349906142b0565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46114de8383836001611ee0565b505050565b60007f0000000000000000000000006e5b6ff605bd8dc2bf99f41853ce1370743b841c73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561155f57507f000000000000000000000000000000000000000000000000000000000000044d46145b1561158c577f8853a6155541b98dfad5b0d26730671c5d5d84d9e48772d5ea0d68d553fdb96090506115fa565b6115f77f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f5c2a8a7287ac45120585c08da8f3591c59cc580e54368d72acf7f432b0d5e5e27fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6611ef2565b90505b90565b6000438210611641576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611638906143ae565b60405180910390fd5b600061164c83611f2c565b905060008460000180549050905060008082905060058311156116cf57600061167484611f7f565b8461167f91906143fd565b905061168e8860000182612078565b60000160009054906101000a900463ffffffff1663ffffffff168563ffffffff1610156116bd578091506116cd565b6001816116ca9190614431565b92505b505b60006116e08860000186858561208d565b90506000811461173457611703886000016001836116fe91906143fd565b612078565b60000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611737565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169550505050505092915050565b61176b81612100565b50565b600061177983610954565b905081600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a461187d818361187886612153565b612165565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6118c7611094565b73ffffffffffffffffffffffffffffffffffffffff166118e5610b78565b73ffffffffffffffffffffffffffffffffffffffff161461193b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611932906144b1565b60405180910390fd5b565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081600001549050919050565b6000808260000180549050905060008114611a7057611a3f83600001600183611a3a91906143fd565b612078565b60000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611a73565b60005b915050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611ae9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae09061451d565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611bda91906135e6565b60405180910390a3505050565b611bf28484846111ea565b611bfe84848484612372565b611c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c34906145af565b60405180910390fd5b50505050565b6000611c56611c506114e3565b836124f9565b9050919050565b6000806000611c6e8787878761252c565b91509150611c7b8161260e565b8192505050949350505050565b600080600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611cd581611a03565b9150611ce081611df8565b50919050565b6060611cf182611049565b6000600660008481526020019081526020016000208054611d1190613d3e565b80601f0160208091040260200160405190810160405280929190818152602001828054611d3d90613d3e565b8015611d8a5780601f10611d5f57610100808354040283529160200191611d8a565b820191906000526020600020905b815481529060010190602001808311611d6d57829003601f168201915b505050505090506000611d9b612774565b90506000815103611db0578192505050611df3565b600082511115611de5578082604051602001611dcd92919061460b565b60405160208183030381529060405292505050611df3565b611dee8461278b565b925050505b919050565b6001816000016000828254019250508190555050565b611e288282604051806020016040528060008152506127f3565b5050565b611e3582611e99565b611e74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6b906146a1565b60405180910390fd5b80600660008481526020019081526020016000209081611e94919061486d565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff16611ebb83611882565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b50505050565b611eec8484848461284e565b50505050565b60008383834630604051602001611f0d95949392919061493f565b6040516020818303038152906040528051906020012090509392505050565b600063ffffffff8016821115611f77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6e90614a04565b60405180910390fd5b819050919050565b6000808203611f915760009050612073565b60006001611f9e8461286b565b901c6001901b90506001818481611fb857611fb7614a24565b5b048201901c90506001818481611fd157611fd0614a24565b5b048201901c90506001818481611fea57611fe9614a24565b5b048201901c9050600181848161200357612002614a24565b5b048201901c9050600181848161201c5761201b614a24565b5b048201901c9050600181848161203557612034614a24565b5b048201901c9050600181848161204e5761204d614a24565b5b048201901c905061206f8182858161206957612068614a24565b5b0461294c565b9150505b919050565b60008260005281602060002001905092915050565b60005b818310156120f55760006120a48484612965565b90508463ffffffff166120b78783612078565b60000160009054906101000a900463ffffffff1663ffffffff1611156120df578092506120ef565b6001816120ec9190614431565b93505b50612090565b819050949350505050565b6121098161298b565b600060066000838152602001908152602001600020805461212990613d3e565b9050146121505760066000828152602001908152602001600020600061214f91906134d5565b5b50565b600061215e82610a5d565b9050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156121a15750600081115b1561236d57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161461228957600080612232612ad984600960008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612aef9092919063ffffffff16565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161227e929190614a53565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461236c57600080612315612b3b84600960008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612aef9092919063ffffffff16565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612361929190614a53565b60405180910390a250505b5b505050565b60006123938473ffffffffffffffffffffffffffffffffffffffff16612b51565b156124ec578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026123bc611094565b8786866040518563ffffffff1660e01b81526004016123de9493929190614ad1565b6020604051808303816000875af192505050801561241a57506040513d601f19601f820116820180604052508101906124179190614b32565b60015b61249c573d806000811461244a576040519150601f19603f3d011682016040523d82523d6000602084013e61244f565b606091505b506000815103612494576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248b906145af565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506124f1565b600190505b949350505050565b6000828260405160200161250e929190614bcc565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612567576000600391509150612605565b60006001878787876040516000815260200160405260405161258c9493929190614c12565b6020604051602081039080840390855afa1580156125ae573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036125fc57600060019250925050612605565b80600092509250505b94509492505050565b6000600481111561262257612621614c57565b5b81600481111561263557612634614c57565b5b0315612771576001600481111561264f5761264e614c57565b5b81600481111561266257612661614c57565b5b036126a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161269990614cd2565b60405180910390fd5b600260048111156126b6576126b5614c57565b5b8160048111156126c9576126c8614c57565b5b03612709576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161270090614d3e565b60405180910390fd5b6003600481111561271d5761271c614c57565b5b8160048111156127305761272f614c57565b5b03612770576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161276790614dd0565b60405180910390fd5b5b50565b606060405180602001604052806000815250905090565b606061279682611049565b60006127a0612774565b905060008151116127c057604051806020016040528060008152506127eb565b806127ca84612b74565b6040516020016127db92919061460b565b6040516020818303038152906040525b915050919050565b6127fd8383612c42565b61280a6000848484612372565b612849576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612840906145af565b60405180910390fd5b505050565b612859848483612e5f565b61286584848484612f1d565b50505050565b600080600090506000608084901c111561288d57608083901c92506080810190505b6000604084901c11156128a857604083901c92506040810190505b6000602084901c11156128c357602083901c92506020810190505b6000601084901c11156128de57601083901c92506010810190505b6000600884901c11156128f957600883901c92506008810190505b6000600484901c111561291457600483901c92506004810190505b6000600284901c111561292f57600283901c92506002810190505b6000600184901c1115612943576001810190505b80915050919050565b600081831061295b578161295d565b825b905092915050565b600060028284186129769190614df0565b8284166129839190614431565b905092915050565b6000612996826109d7565b90506129a6816000846001611eda565b6129af826109d7565b90506004600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612ad5816000846001611ee0565b5050565b60008183612ae791906143fd565b905092915050565b600080612b2f85612b2a612b0288611a11565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16868863ffffffff16565b612f23565b91509150935093915050565b60008183612b499190614431565b905092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606060006001612b8384612f91565b01905060008167ffffffffffffffff811115612ba257612ba1613932565b5b6040519080825280601f01601f191660200182016040528015612bd45781602001600182028036833780820191505090505b509050600082602001820190505b600115612c37578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612c2b57612c2a614a24565b5b04945060008503612be2575b819350505050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612cb1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca890614e6d565b60405180910390fd5b612cba81611e99565b15612cfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cf190614ed9565b60405180910390fd5b612d08600083836001611eda565b612d1181611e99565b15612d51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d4890614ed9565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612e5b600083836001611ee0565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603612eae57612eab612b3b82600a612aef9092919063ffffffff16565b50505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612efd57612efa612ad982600a612aef9092919063ffffffff16565b50505b612f18612f0984610954565b612f1284610954565b83612165565b505050565b50505050565b600080612f4484600001612f3643611f2c565b612f3f866130e4565b61314f565b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169150807bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169050915091509250929050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612fef577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612fe557612fe4614a24565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061302c576d04ee2d6d415b85acef8100000000838161302257613021614a24565b5b0492506020810190505b662386f26fc10000831061305b57662386f26fc10000838161305157613050614a24565b5b0492506010810190505b6305f5e1008310613084576305f5e100838161307a57613079614a24565b5b0492506008810190505b61271083106130a957612710838161309f5761309e614a24565b5b0492506004810190505b606483106130cc57606483816130c2576130c1614a24565b5b0492506002810190505b600a83106130db576001810190505b80915050919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115613147576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313e90614f6b565b60405180910390fd5b819050919050565b60008060008580549050905060008111156133e557600061317c8760018461317791906143fd565b612078565b6040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152505090508563ffffffff16816000015163ffffffff161115613270576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326790614fd7565b60405180910390fd5b8563ffffffff16816000015163ffffffff16036132f4578461329e8860018561329991906143fd565b612078565b60000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602179055506133d4565b8660405180604001604052808863ffffffff168152602001877bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b8060200151859350935050506134cd565b8560405180604001604052808763ffffffff168152602001867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550505060008492509250505b935093915050565b5080546134e190613d3e565b6000825580601f106134f35750613512565b601f0160209004906000526020600020908101906135119190613515565b5b50565b5b8082111561352e576000816000905550600101613516565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61357b81613546565b811461358657600080fd5b50565b60008135905061359881613572565b92915050565b6000602082840312156135b4576135b361353c565b5b60006135c284828501613589565b91505092915050565b60008115159050919050565b6135e0816135cb565b82525050565b60006020820190506135fb60008301846135d7565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561363b578082015181840152602081019050613620565b60008484015250505050565b6000601f19601f8301169050919050565b600061366382613601565b61366d818561360c565b935061367d81856020860161361d565b61368681613647565b840191505092915050565b600060208201905081810360008301526136ab8184613658565b905092915050565b6000819050919050565b6136c6816136b3565b81146136d157600080fd5b50565b6000813590506136e3816136bd565b92915050565b6000602082840312156136ff576136fe61353c565b5b600061370d848285016136d4565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061374182613716565b9050919050565b61375181613736565b82525050565b600060208201905061376c6000830184613748565b92915050565b61377b81613736565b811461378657600080fd5b50565b60008135905061379881613772565b92915050565b600080604083850312156137b5576137b461353c565b5b60006137c385828601613789565b92505060206137d4858286016136d4565b9150509250929050565b6000806000606084860312156137f7576137f661353c565b5b600061380586828701613789565b935050602061381686828701613789565b9250506040613827868287016136d4565b9150509250925092565b6000819050919050565b61384481613831565b82525050565b600060208201905061385f600083018461383b565b92915050565b61386e816136b3565b82525050565b60006020820190506138896000830184613865565b92915050565b6000602082840312156138a5576138a461353c565b5b60006138b384828501613789565b91505092915050565b6138c5816135cb565b81146138d057600080fd5b50565b6000813590506138e2816138bc565b92915050565b600080604083850312156138ff576138fe61353c565b5b600061390d85828601613789565b925050602061391e858286016138d3565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61396a82613647565b810181811067ffffffffffffffff8211171561398957613988613932565b5b80604052505050565b600061399c613532565b90506139a88282613961565b919050565b600067ffffffffffffffff8211156139c8576139c7613932565b5b6139d182613647565b9050602081019050919050565b82818337600083830152505050565b6000613a006139fb846139ad565b613992565b905082815260208101848484011115613a1c57613a1b61392d565b5b613a278482856139de565b509392505050565b600082601f830112613a4457613a43613928565b5b8135613a548482602086016139ed565b91505092915050565b60008060008060808587031215613a7757613a7661353c565b5b6000613a8587828801613789565b9450506020613a9687828801613789565b9350506040613aa7878288016136d4565b925050606085013567ffffffffffffffff811115613ac857613ac7613541565b5b613ad487828801613a2f565b91505092959194509250565b600060ff82169050919050565b613af681613ae0565b8114613b0157600080fd5b50565b600081359050613b1381613aed565b92915050565b613b2281613831565b8114613b2d57600080fd5b50565b600081359050613b3f81613b19565b92915050565b60008060008060008060c08789031215613b6257613b6161353c565b5b6000613b7089828a01613789565b9650506020613b8189828a016136d4565b9550506040613b9289828a016136d4565b9450506060613ba389828a01613b04565b9350506080613bb489828a01613b30565b92505060a0613bc589828a01613b30565b9150509295509295509295565b600067ffffffffffffffff821115613bed57613bec613932565b5b613bf682613647565b9050602081019050919050565b6000613c16613c1184613bd2565b613992565b905082815260208101848484011115613c3257613c3161392d565b5b613c3d8482856139de565b509392505050565b600082601f830112613c5a57613c59613928565b5b8135613c6a848260208601613c03565b91505092915050565b60008060408385031215613c8a57613c8961353c565b5b6000613c9885828601613789565b925050602083013567ffffffffffffffff811115613cb957613cb8613541565b5b613cc585828601613c45565b9150509250929050565b60008060408385031215613ce657613ce561353c565b5b6000613cf485828601613789565b9250506020613d0585828601613789565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613d5657607f821691505b602082108103613d6957613d68613d0f565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000613dcb60218361360c565b9150613dd682613d6f565b604082019050919050565b60006020820190508181036000830152613dfa81613dbe565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000613e5d603d8361360c565b9150613e6882613e01565b604082019050919050565b60006020820190508181036000830152613e8c81613e50565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613eef602d8361360c565b9150613efa82613e93565b604082019050919050565b60006020820190508181036000830152613f1e81613ee2565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b6000613f5b60188361360c565b9150613f6682613f25565b602082019050919050565b60006020820190508181036000830152613f8a81613f4e565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613fed60298361360c565b9150613ff882613f91565b604082019050919050565b6000602082019050818103600083015261401c81613fe0565b9050919050565b7f566f7465733a20626c6f636b206e6f7420796574206d696e6564000000000000600082015250565b6000614059601a8361360c565b915061406482614023565b602082019050919050565b600060208201905081810360008301526140888161404c565b9050919050565b7f566f7465733a207369676e617475726520657870697265640000000000000000600082015250565b60006140c560188361360c565b91506140d08261408f565b602082019050919050565b600060208201905081810360008301526140f4816140b8565b9050919050565b6000608082019050614110600083018761383b565b61411d6020830186613748565b61412a6040830185613865565b6141376060830184613865565b95945050505050565b7f566f7465733a20696e76616c6964206e6f6e6365000000000000000000000000600082015250565b600061417660148361360c565b915061418182614140565b602082019050919050565b600060208201905081810360008301526141a581614169565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061420860268361360c565b9150614213826141ac565b604082019050919050565b60006020820190508181036000830152614237816141fb565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061429a60258361360c565b91506142a58261423e565b604082019050919050565b600060208201905081810360008301526142c98161428d565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061432c60248361360c565b9150614337826142d0565b604082019050919050565b6000602082019050818103600083015261435b8161431f565b9050919050565b7f436865636b706f696e74733a20626c6f636b206e6f7420796574206d696e6564600082015250565b600061439860208361360c565b91506143a382614362565b602082019050919050565b600060208201905081810360008301526143c78161438b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614408826136b3565b9150614413836136b3565b925082820390508181111561442b5761442a6143ce565b5b92915050565b600061443c826136b3565b9150614447836136b3565b925082820190508082111561445f5761445e6143ce565b5b92915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061449b60208361360c565b91506144a682614465565b602082019050919050565b600060208201905081810360008301526144ca8161448e565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061450760198361360c565b9150614512826144d1565b602082019050919050565b60006020820190508181036000830152614536816144fa565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b600061459960328361360c565b91506145a48261453d565b604082019050919050565b600060208201905081810360008301526145c88161458c565b9050919050565b600081905092915050565b60006145e582613601565b6145ef81856145cf565b93506145ff81856020860161361d565b80840191505092915050565b600061461782856145da565b915061462382846145da565b91508190509392505050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b600061468b602e8361360c565b91506146968261462f565b604082019050919050565b600060208201905081810360008301526146ba8161467e565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026147237fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826146e6565b61472d86836146e6565b95508019841693508086168417925050509392505050565b6000819050919050565b600061476a614765614760846136b3565b614745565b6136b3565b9050919050565b6000819050919050565b6147848361474f565b61479861479082614771565b8484546146f3565b825550505050565b600090565b6147ad6147a0565b6147b881848461477b565b505050565b5b818110156147dc576147d16000826147a5565b6001810190506147be565b5050565b601f821115614821576147f2816146c1565b6147fb846146d6565b8101602085101561480a578190505b61481e614816856146d6565b8301826147bd565b50505b505050565b600082821c905092915050565b600061484460001984600802614826565b1980831691505092915050565b600061485d8383614833565b9150826002028217905092915050565b61487682613601565b67ffffffffffffffff81111561488f5761488e613932565b5b6148998254613d3e565b6148a48282856147e0565b600060209050601f8311600181146148d757600084156148c5578287015190505b6148cf8582614851565b865550614937565b601f1984166148e5866146c1565b60005b8281101561490d578489015182556001820191506020850194506020810190506148e8565b8683101561492a5784890151614926601f891682614833565b8355505b6001600288020188555050505b505050505050565b600060a082019050614954600083018861383b565b614961602083018761383b565b61496e604083018661383b565b61497b6060830185613865565b6149886080830184613748565b9695505050505050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b60006149ee60268361360c565b91506149f982614992565b604082019050919050565b60006020820190508181036000830152614a1d816149e1565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000604082019050614a686000830185613865565b614a756020830184613865565b9392505050565b600081519050919050565b600082825260208201905092915050565b6000614aa382614a7c565b614aad8185614a87565b9350614abd81856020860161361d565b614ac681613647565b840191505092915050565b6000608082019050614ae66000830187613748565b614af36020830186613748565b614b006040830185613865565b8181036060830152614b128184614a98565b905095945050505050565b600081519050614b2c81613572565b92915050565b600060208284031215614b4857614b4761353c565b5b6000614b5684828501614b1d565b91505092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000614b956002836145cf565b9150614ba082614b5f565b600282019050919050565b6000819050919050565b614bc6614bc182613831565b614bab565b82525050565b6000614bd782614b88565b9150614be38285614bb5565b602082019150614bf38284614bb5565b6020820191508190509392505050565b614c0c81613ae0565b82525050565b6000608082019050614c27600083018761383b565b614c346020830186614c03565b614c41604083018561383b565b614c4e606083018461383b565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b6000614cbc60188361360c565b9150614cc782614c86565b602082019050919050565b60006020820190508181036000830152614ceb81614caf565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b6000614d28601f8361360c565b9150614d3382614cf2565b602082019050919050565b60006020820190508181036000830152614d5781614d1b565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b6000614dba60228361360c565b9150614dc582614d5e565b604082019050919050565b60006020820190508181036000830152614de981614dad565b9050919050565b6000614dfb826136b3565b9150614e06836136b3565b925082614e1657614e15614a24565b5b828204905092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614e5760208361360c565b9150614e6282614e21565b602082019050919050565b60006020820190508181036000830152614e8681614e4a565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614ec3601c8361360c565b9150614ece82614e8d565b602082019050919050565b60006020820190508181036000830152614ef281614eb6565b9050919050565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b6000614f5560278361360c565b9150614f6082614ef9565b604082019050919050565b60006020820190508181036000830152614f8481614f48565b9050919050565b7f436865636b706f696e743a20696e76616c6964206b6579000000000000000000600082015250565b6000614fc160178361360c565b9150614fcc82614f8b565b602082019050919050565b60006020820190508181036000830152614ff081614fb4565b905091905056fea26469706673582212201ab0472614a8e981c825c09616f09840d3907562d4cb1b2e55504baf1ee5b24164736f6c63430008130033

Deployed Bytecode Sourcemap

140101:1140:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119273:305;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120201:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;121713:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;121231:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;122413:335;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96546:106;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91570:200;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;122819:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;137822:242;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;92787:129;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93003:150;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;119911:223;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;119642:207;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98704:103;;;:::i;:::-;;96284:119;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98056:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92246:253;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;120370:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91203:146;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;121956:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;123075:322;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93236:581;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;141042:196;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;140370:236;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;122182:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98962:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;119273:305;119375:4;119427:25;119412:40;;;:11;:40;;;;:105;;;;119484:33;119469:48;;;:11;:48;;;;119412:105;:158;;;;119534:36;119558:11;119534:23;:36::i;:::-;119412:158;119392:178;;119273:305;;;:::o;120201:100::-;120255:13;120288:5;120281:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120201:100;:::o;121713:171::-;121789:7;121809:23;121824:7;121809:14;:23::i;:::-;121852:15;:24;121868:7;121852:24;;;;;;;;;;;;;;;;;;;;;121845:31;;121713:171;;;:::o;121231:416::-;121312:13;121328:23;121343:7;121328:14;:23::i;:::-;121312:39;;121376:5;121370:11;;:2;:11;;;121362:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;121470:5;121454:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;121479:37;121496:5;121503:12;:10;:12::i;:::-;121479:16;:37::i;:::-;121454:62;121432:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;121618:21;121627:2;121631:7;121618:8;:21::i;:::-;121301:346;121231:416;;:::o;122413:335::-;122608:41;122627:12;:10;:12::i;:::-;122641:7;122608:18;:41::i;:::-;122600:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;122712:28;122722:4;122728:2;122732:7;122712:9;:28::i;:::-;122413:335;;;:::o;96546:106::-;96597:7;96624:20;:18;:20::i;:::-;96617:27;;96546:106;:::o;91570:200::-;91668:7;91695:67;91750:11;91695:20;:29;91716:7;91695:29;;;;;;;;;;;;;;;:54;;:67;;;;:::i;:::-;91688:74;;91570:200;;;;:::o;122819:185::-;122957:39;122974:4;122980:2;122984:7;122957:39;;;;;;;;;;;;:16;:39::i;:::-;122819:185;;;:::o;137822:242::-;137940:41;137959:12;:10;:12::i;:::-;137973:7;137940:18;:41::i;:::-;137932:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;138042:14;138048:7;138042:5;:14::i;:::-;137822:242;:::o;92787:129::-;92861:7;92888:11;:20;92900:7;92888:20;;;;;;;;;;;;;;;;;;;;;;;;;92881:27;;92787:129;;;:::o;93003:150::-;93075:15;93093:12;:10;:12::i;:::-;93075:30;;93116:29;93126:7;93135:9;93116;:29::i;:::-;93064:89;93003:150;:::o;119911:223::-;119983:7;120003:13;120019:17;120028:7;120019:8;:17::i;:::-;120003:33;;120072:1;120055:19;;:5;:19;;;120047:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;120121:5;120114:12;;;119911:223;;;:::o;119642:207::-;119714:7;119759:1;119742:19;;:5;:19;;;119734:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;119825:9;:16;119835:5;119825:16;;;;;;;;;;;;;;;;119818:23;;119642:207;;;:::o;98704:103::-;97942:13;:11;:13::i;:::-;98769:30:::1;98796:1;98769:18;:30::i;:::-;98704:103::o:0;96284:119::-;96344:7;96371:24;:7;:14;96379:5;96371:14;;;;;;;;;;;;;;;:22;:24::i;:::-;96364:31;;96284:119;;;:::o;98056:87::-;98102:7;98129:6;;;;;;;;;;;98122:13;;98056:87;:::o;92246:253::-;92333:7;92375:12;92361:11;:26;92353:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;92436:55;92479:11;92436:17;:42;;:55;;;;:::i;:::-;92429:62;;92246:253;;;:::o;120370:104::-;120426:13;120459:7;120452:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120370:104;:::o;91203:146::-;91276:7;91303:38;:20;:29;91324:7;91303:29;;;;;;;;;;;;;;;:36;:38::i;:::-;91296:45;;;;91203:146;;;:::o;121956:155::-;122051:52;122070:12;:10;:12::i;:::-;122084:8;122094;122051:18;:52::i;:::-;121956:155;;:::o;123075:322::-;123249:41;123268:12;:10;:12::i;:::-;123282:7;123249:18;:41::i;:::-;123241:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;123351:38;123365:4;123371:2;123375:7;123384:4;123351:13;:38::i;:::-;123075:322;;;;:::o;93236:581::-;93463:6;93444:15;:25;;93436:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;93509:14;93526:174;93554:87;90792:71;93614:9;93625:5;93632:6;93581:58;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;93571:69;;;;;;93554:16;:87::i;:::-;93656:1;93672;93688;93526:13;:174::i;:::-;93509:191;;93728:17;93738:6;93728:9;:17::i;:::-;93719:5;:26;93711:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;93781:28;93791:6;93799:9;93781;:28::i;:::-;93425:392;93236:581;;;;;;:::o;141042:196::-;141169:13;141207:23;141222:7;141207:14;:23::i;:::-;141200:30;;141042:196;;;:::o;140370:236::-;97942:13;:11;:13::i;:::-;140447:15:::1;140465:25;:15;:23;:25::i;:::-;140447:43;;140501:27;:15;:25;:27::i;:::-;140539:22;140549:2;140553:7;140539:9;:22::i;:::-;140572:26;140585:7;140594:3;140572:12;:26::i;:::-;140436:170;140370:236:::0;;:::o;122182:164::-;122279:4;122303:18;:25;122322:5;122303:25;;;;;;;;;;;;;;;:35;122329:8;122303:35;;;;;;;;;;;;;;;;;;;;;;;;;122296:42;;122182:164;;;;:::o;98962:201::-;97942:13;:11;:13::i;:::-;99071:1:::1;99051:22;;:8;:22;;::::0;99043:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;99127:28;99146:8;99127:18;:28::i;:::-;98962:201:::0;:::o;111785:157::-;111870:4;111909:25;111894:40;;;:11;:40;;;;111887:47;;111785:157;;;:::o;131532:135::-;131614:16;131622:7;131614;:16::i;:::-;131606:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;131532:135;:::o;88812:98::-;88865:7;88892:10;88885:17;;88812:98;:::o;130811:174::-;130913:2;130886:15;:24;130902:7;130886:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;130969:7;130965:2;130931:46;;130940:23;130955:7;130940:14;:23::i;:::-;130931:46;;;;;;;;;;;;130811:174;;:::o;125430:264::-;125523:4;125540:13;125556:23;125571:7;125556:14;:23::i;:::-;125540:39;;125609:5;125598:16;;:7;:16;;;:52;;;;125618:32;125635:5;125642:7;125618:16;:32::i;:::-;125598:52;:87;;;;125678:7;125654:31;;:20;125666:7;125654:11;:20::i;:::-;:31;;;125598:87;125590:96;;;125430:264;;;;:::o;129429:1263::-;129588:4;129561:31;;:23;129576:7;129561:14;:23::i;:::-;:31;;;129553:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;129667:1;129653:16;;:2;:16;;;129645:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;129723:42;129744:4;129750:2;129754:7;129763:1;129723:20;:42::i;:::-;129895:4;129868:31;;:23;129883:7;129868:14;:23::i;:::-;:31;;;129860:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;130013:15;:24;130029:7;130013:24;;;;;;;;;;;;130006:31;;;;;;;;;;;130508:1;130489:9;:15;130499:4;130489:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;130541:1;130524:9;:13;130534:2;130524:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;130583:2;130564:7;:16;130572:7;130564:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;130622:7;130618:2;130603:27;;130612:4;130603:27;;;;;;;;;;;;130643:41;130663:4;130669:2;130673:7;130682:1;130643:19;:41::i;:::-;129429:1263;;;:::o;86474:314::-;86527:7;86568:12;86551:29;;86559:4;86551:29;;;:66;;;;;86601:16;86584:13;:33;86551:66;86547:234;;;86641:24;86634:31;;;;86547:234;86705:64;86727:10;86739:12;86753:15;86705:21;:64::i;:::-;86698:71;;86474:314;;:::o;54860:785::-;54960:7;55002:12;54988:11;:26;54980:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;55062:10;55075:30;55093:11;55075:17;:30::i;:::-;55062:43;;55118:11;55132:4;:17;;:24;;;;55118:38;;55169:11;55195:12;55210:3;55195:18;;55236:1;55230:3;:7;55226:249;;;55254:11;55274:14;55284:3;55274:9;:14::i;:::-;55268:3;:20;;;;:::i;:::-;55254:34;;55313:37;55327:4;:17;;55346:3;55313:13;:37::i;:::-;:50;;;;;;;;;;;;55307:56;;:3;:56;;;55303:161;;;55391:3;55384:10;;55303:161;;;55447:1;55441:3;:7;;;;:::i;:::-;55435:13;;55303:161;55239:236;55226:249;55487:11;55501:53;55520:4;:17;;55539:3;55544;55549:4;55501:18;:53::i;:::-;55487:67;;55581:1;55574:3;:8;:63;;55589:41;55603:4;:17;;55628:1;55622:3;:7;;;;:::i;:::-;55589:13;:41::i;:::-;:48;;;;;;;;;;;;55574:63;;;55585:1;55574:63;55567:70;;;;;;;;;54860:785;;;;:::o;140919:115::-;141006:20;141018:7;141006:11;:20::i;:::-;140919:115;:::o;94002:319::-;94085:19;94107:18;94117:7;94107:9;:18::i;:::-;94085:40;;94159:9;94136:11;:20;94148:7;94136:20;;;;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;94224:9;94186:48;;94211:11;94186:48;;94202:7;94186:48;;;;;;;;;;;;94245:68;94264:11;94277:9;94288:24;94304:7;94288:15;:24::i;:::-;94245:18;:68::i;:::-;94074:247;94002:319;;:::o;124705:117::-;124771:7;124798;:16;124806:7;124798:16;;;;;;;;;;;;;;;;;;;;;124791:23;;124705:117;;;:::o;98221:132::-;98296:12;:10;:12::i;:::-;98285:23;;:7;:5;:7::i;:::-;:23;;;98277:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;98221:132::o;99323:191::-;99397:16;99416:6;;;;;;;;;;;99397:25;;99442:8;99433:6;;:17;;;;;;;;;;;;;;;;;;99497:8;99466:40;;99487:8;99466:40;;;;;;;;;;;;99386:128;99323:191;:::o;39313:114::-;39378:7;39405;:14;;;39398:21;;39313:114;;;:::o;56630:208::-;56691:7;56711:11;56725:4;:17;;:24;;;;56711:38;;56774:1;56767:3;:8;:63;;56782:41;56796:4;:17;;56821:1;56815:3;:7;;;;:::i;:::-;56782:13;:41::i;:::-;:48;;;;;;;;;;;;56767:63;;;56778:1;56767:63;56760:70;;;56630:208;;;:::o;131128:315::-;131283:8;131274:17;;:5;:17;;;131266:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;131370:8;131332:18;:25;131351:5;131332:25;;;;;;;;;;;;;;;:35;131358:8;131332:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;131416:8;131394:41;;131409:5;131394:41;;;131426:8;131394:41;;;;;;:::i;:::-;;;;;;;;131128:315;;;:::o;124278:313::-;124434:28;124444:4;124450:2;124454:7;124434:9;:28::i;:::-;124481:47;124504:4;124510:2;124514:7;124523:4;124481:22;:47::i;:::-;124473:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;124278:313;;;;:::o;87701:167::-;87778:7;87805:55;87827:20;:18;:20::i;:::-;87849:10;87805:21;:55::i;:::-;87798:62;;87701:167;;;:::o;81347:279::-;81475:7;81496:17;81515:18;81537:25;81548:4;81554:1;81557;81560;81537:10;:25::i;:::-;81495:67;;;;81573:18;81585:5;81573:11;:18::i;:::-;81609:9;81602:16;;;;81347:279;;;;;;:::o;96012:207::-;96072:15;96100:30;96133:7;:14;96141:5;96133:14;;;;;;;;;;;;;;;96100:47;;96168:15;:5;:13;:15::i;:::-;96158:25;;96194:17;:5;:15;:17::i;:::-;96089:130;96012:207;;;:::o;138597:624::-;138670:13;138696:23;138711:7;138696:14;:23::i;:::-;138732;138758:10;:19;138769:7;138758:19;;;;;;;;;;;138732:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;138788:18;138809:10;:8;:10::i;:::-;138788:31;;138917:1;138901:4;138895:18;:23;138891:72;;138942:9;138935:16;;;;;;138891:72;139093:1;139073:9;139067:23;:27;139063:108;;;139142:4;139148:9;139125:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;139111:48;;;;;;139063:108;139190:23;139205:7;139190:14;:23::i;:::-;139183:30;;;;138597:624;;;;:::o;39435:127::-;39542:1;39524:7;:14;;;:19;;;;;;;;;;;39435:127;:::o;126036:110::-;126112:26;126122:2;126126:7;126112:26;;;;;;;;;;;;:9;:26::i;:::-;126036:110;;:::o;139377:217::-;139477:16;139485:7;139477;:16::i;:::-;139469:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;139577:9;139555:10;:19;139566:7;139555:19;;;;;;;;;;;:31;;;;;;:::i;:::-;;139377:217;;:::o;125135:128::-;125200:4;125253:1;125224:31;;:17;125233:7;125224:8;:17::i;:::-;:31;;;;125217:38;;125135:128;;;:::o;133816:159::-;;;;;:::o;140684:227::-;140848:55;140874:4;140880:2;140884:7;140893:9;140848:25;:55::i;:::-;140684:227;;;;:::o;86796:263::-;86940:7;86988:8;86998;87008:11;87021:13;87044:4;86977:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;86967:84;;;;;;86960:91;;86796:263;;;;;:::o;17979:190::-;18035:6;18071:16;18062:25;;:5;:25;;18054:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;18155:5;18141:20;;17979:190;;;:::o;46368:1673::-;46416:7;46445:1;46440;:6;46436:47;;46470:1;46463:8;;;;46436:47;47174:14;47208:1;47197:7;47202:1;47197:4;:7::i;:::-;:12;;47191:1;:19;;47174:36;;47676:1;47665:6;47661:1;:10;;;;;:::i;:::-;;;47652:6;:19;47651:26;;47642:35;;47726:1;47715:6;47711:1;:10;;;;;:::i;:::-;;;47702:6;:19;47701:26;;47692:35;;47776:1;47765:6;47761:1;:10;;;;;:::i;:::-;;;47752:6;:19;47751:26;;47742:35;;47826:1;47815:6;47811:1;:10;;;;;:::i;:::-;;;47802:6;:19;47801:26;;47792:35;;47876:1;47865:6;47861:1;:10;;;;;:::i;:::-;;;47852:6;:19;47851:26;;47842:35;;47926:1;47915:6;47911:1;:10;;;;;:::i;:::-;;;47902:6;:19;47901:26;;47892:35;;47976:1;47965:6;47961:1;:10;;;;;:::i;:::-;;;47952:6;:19;47951:26;;47942:35;;47999:23;48003:6;48015;48011:1;:10;;;;;:::i;:::-;;;47999:3;:23::i;:::-;47992:30;;;46368:1673;;;;:::o;60533:242::-;60618:25;60690:9;60687:1;60680:20;60753:3;60746:4;60743:1;60733:18;60729:28;60714:43;;60533:242;;;;:::o;59131:453::-;59290:7;59310:245;59323:4;59317:3;:10;59310:245;;;59344:11;59358:23;59371:3;59376:4;59358:12;:23::i;:::-;59344:37;;59440:3;59400:43;;:24;59414:4;59420:3;59400:13;:24::i;:::-;:37;;;;;;;;;;;;:43;;;59396:148;;;59471:3;59464:10;;59396:148;;;59527:1;59521:3;:7;;;;:::i;:::-;59515:13;;59396:148;59329:226;59310:245;;;59572:4;59565:11;;59131:453;;;;;;:::o;139819:206::-;139888:20;139900:7;139888:11;:20::i;:::-;139962:1;139931:10;:19;139942:7;139931:19;;;;;;;;;;;139925:33;;;;;:::i;:::-;;;:38;139921:97;;139987:10;:19;139998:7;139987:19;;;;;;;;;;;;139980:26;;;;:::i;:::-;139921:97;139819:206;:::o;136797:135::-;136879:7;136906:18;136916:7;136906:9;:18::i;:::-;136899:25;;136797:135;;;:::o;95049:625::-;95184:2;95176:10;;:4;:10;;;;:24;;;;;95199:1;95190:6;:10;95176:24;95172:495;;;95237:1;95221:18;;:4;:18;;;95217:218;;95261:16;95279;95299:50;95331:9;95342:6;95299:20;:26;95320:4;95299:26;;;;;;;;;;;;;;;:31;;:50;;;;;:::i;:::-;95260:89;;;;95394:4;95373:46;;;95400:8;95410;95373:46;;;;;;;:::i;:::-;;;;;;;;95241:194;;95217:218;95467:1;95453:16;;:2;:16;;;95449:207;;95491:16;95509;95529:43;95559:4;95565:6;95529:20;:24;95550:2;95529:24;;;;;;;;;;;;;;;:29;;:43;;;;;:::i;:::-;95490:82;;;;95617:2;95596:44;;;95621:8;95631;95596:44;;;;;;;:::i;:::-;;;;;;;;95471:185;;95449:207;95172:495;95049:625;;;:::o;132231:853::-;132385:4;132406:15;:2;:13;;;:15::i;:::-;132402:675;;;132458:2;132442:36;;;132479:12;:10;:12::i;:::-;132493:4;132499:7;132508:4;132442:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;132438:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;132700:1;132683:6;:13;:18;132679:328;;132726:60;;;;;;;;;;:::i;:::-;;;;;;;;132679:328;132957:6;132951:13;132942:6;132938:2;132934:15;132927:38;132438:584;132574:41;;;132564:51;;;:6;:51;;;;132557:58;;;;;132402:675;133061:4;133054:11;;132231:853;;;;;;;:::o;83038:196::-;83131:7;83197:15;83214:10;83168:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83158:68;;;;;;83151:75;;83038:196;;;;:::o;79688:1520::-;79819:7;79828:12;80753:66;80748:1;80740:10;;:79;80736:163;;;80852:1;80856:30;80836:51;;;;;;80736:163;80996:14;81013:24;81023:4;81029:1;81032;81035;81013:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80996:41;;81070:1;81052:20;;:6;:20;;;81048:103;;81105:1;81109:29;81089:50;;;;;;;81048:103;81171:6;81179:20;81163:37;;;;;79688:1520;;;;;;;;:::o;75080:521::-;75158:20;75149:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;75145:449;75195:7;75145:449;75256:29;75247:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;75243:351;;75302:34;;;;;;;;;;:::i;:::-;;;;;;;;75243:351;75367:35;75358:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;75354:240;;75419:41;;;;;;;;;;:::i;:::-;;;;;;;;75354:240;75491:30;75482:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;75478:116;;75538:44;;;;;;;;;;:::i;:::-;;;;;;;;75478:116;75080:521;;:::o;121075:94::-;121126:13;121152:9;;;;;;;;;;;;;;121075:94;:::o;120545:281::-;120618:13;120644:23;120659:7;120644:14;:23::i;:::-;120680:21;120704:10;:8;:10::i;:::-;120680:34;;120756:1;120738:7;120732:21;:25;:86;;;;;;;;;;;;;;;;;120784:7;120793:18;:7;:16;:18::i;:::-;120767:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;120732:86;120725:93;;;120545:281;;;:::o;126373:319::-;126502:18;126508:2;126512:7;126502:5;:18::i;:::-;126553:53;126584:1;126588:2;126592:7;126601:4;126553:22;:53::i;:::-;126531:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;126373:319;;;:::o;136428:296::-;136604:41;136625:4;136631:2;136635:9;136604:20;:41::i;:::-;136656:60;136682:4;136688:2;136692:12;136706:9;136656:25;:60::i;:::-;136428:296;;;;:::o;48518:1019::-;48570:7;48590:14;48607:1;48590:18;;48663:1;48657:3;48648:5;:12;;:16;48644:102;;;48695:3;48685:13;;;;;48727:3;48717:13;;;;48644:102;48778:1;48773:2;48764:5;:11;;:15;48760:99;;;48810:2;48800:12;;;;;48841:2;48831:12;;;;48760:99;48891:1;48886:2;48877:5;:11;;:15;48873:99;;;48923:2;48913:12;;;;;48954:2;48944:12;;;;48873:99;49004:1;48999:2;48990:5;:11;;:15;48986:99;;;49036:2;49026:12;;;;;49067:2;49057:12;;;;48986:99;49116:1;49112;49103:5;:10;;:14;49099:96;;;49148:1;49138:11;;;;;49178:1;49168:11;;;;49099:96;49226:1;49222;49213:5;:10;;:14;49209:96;;;49258:1;49248:11;;;;;49288:1;49278:11;;;;49209:96;49336:1;49332;49323:5;:10;;:14;49319:96;;;49368:1;49358:11;;;;;49398:1;49388:11;;;;49319:96;49446:1;49442;49433:5;:10;;:14;49429:66;;;49478:1;49468:11;;;;49429:66;49523:6;49516:13;;;48518:1019;;;:::o;40544:106::-;40602:7;40633:1;40629;:5;:13;;40641:1;40629:13;;;40637:1;40629:13;40622:20;;40544:106;;;;:::o;40769:156::-;40831:7;40916:1;40911;40907;:5;40906:11;;;;:::i;:::-;40901:1;40897;:5;40896:21;;;;:::i;:::-;40889:28;;40769:156;;;;:::o;128309:783::-;128369:13;128385:23;128400:7;128385:14;:23::i;:::-;128369:39;;128421:51;128442:5;128457:1;128461:7;128470:1;128421:20;:51::i;:::-;128585:23;128600:7;128585:14;:23::i;:::-;128577:31;;128656:15;:24;128672:7;128656:24;;;;;;;;;;;;128649:31;;;;;;;;;;;128921:1;128901:9;:16;128911:5;128901:16;;;;;;;;;;;;;;;;:21;;;;;;;;;;;128951:7;:16;128959:7;128951:16;;;;;;;;;;;;128944:23;;;;;;;;;;;129013:7;129009:1;128985:36;;128994:5;128985:36;;;;;;;;;;;;129034:50;129054:5;129069:1;129073:7;129082:1;129034:19;:50::i;:::-;128358:734;128309:783;:::o;95788:103::-;95851:7;95882:1;95878;:5;;;;:::i;:::-;95871:12;;95788:103;;;;:::o;56269:236::-;56426:7;56435;56462:35;56467:4;56473:23;56476:12;56483:4;56476:6;:12::i;:::-;56473:23;;56490:5;56473:2;:23;;:::i;:::-;56462:4;:35::i;:::-;56455:42;;;;56269:236;;;;;;:::o;95682:98::-;95740:7;95771:1;95767;:5;;;;:::i;:::-;95760:12;;95682:98;;;;:::o;100754:326::-;100814:4;101071:1;101049:7;:19;;;:23;101042:30;;100754:326;;;:::o;72586:716::-;72642:13;72693:14;72730:1;72710:17;72721:5;72710:10;:17::i;:::-;:21;72693:38;;72746:20;72780:6;72769:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72746:41;;72802:11;72931:6;72927:2;72923:15;72915:6;72911:28;72904:35;;72968:288;72975:4;72968:288;;;73000:5;;;;;;;;73142:8;73137:2;73130:5;73126:14;73121:30;73116:3;73108:44;73198:2;73189:11;;;;;;:::i;:::-;;;;;73232:1;73223:5;:10;72968:288;73219:21;72968:288;73277:6;73270:13;;;;;72586:716;;;:::o;127028:942::-;127122:1;127108:16;;:2;:16;;;127100:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;127181:16;127189:7;127181;:16::i;:::-;127180:17;127172:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;127243:48;127272:1;127276:2;127280:7;127289:1;127243:20;:48::i;:::-;127390:16;127398:7;127390;:16::i;:::-;127389:17;127381:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;127805:1;127788:9;:13;127798:2;127788:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;127849:2;127830:7;:16;127838:7;127830:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;127894:7;127890:2;127869:33;;127886:1;127869:33;;;;;;;;;;;;127915:47;127943:1;127947:2;127951:7;127960:1;127915:19;:47::i;:::-;127028:942;;:::o;94561:397::-;94715:1;94699:18;;:4;:18;;;94695:87;;94734:36;94757:4;94763:6;94734:17;:22;;:36;;;;;:::i;:::-;;;94695:87;94810:1;94796:16;;:2;:16;;;94792:90;;94829:41;94852:9;94863:6;94829:17;:22;;:41;;;;;:::i;:::-;;;94792:90;94892:58;94911:15;94921:4;94911:9;:15::i;:::-;94928:13;94938:2;94928:9;:13::i;:::-;94943:6;94892:18;:58::i;:::-;94561:397;;;:::o;134697:158::-;;;;;:::o;55830:199::-;55899:7;55908;55935:86;55943:4;:17;;55962:31;55980:12;55962:17;:31::i;:::-;55995:25;56014:5;55995:18;:25::i;:::-;55935:7;:86::i;:::-;55928:93;;;;;;;;;;;;;;55830:199;;;;;:::o;50077:922::-;50130:7;50150:14;50167:1;50150:18;;50217:6;50208:5;:15;50204:102;;50253:6;50244:15;;;;;;:::i;:::-;;;;;50288:2;50278:12;;;;50204:102;50333:6;50324:5;:15;50320:102;;50369:6;50360:15;;;;;;:::i;:::-;;;;;50404:2;50394:12;;;;50320:102;50449:6;50440:5;:15;50436:102;;50485:6;50476:15;;;;;;:::i;:::-;;;;;50520:2;50510:12;;;;50436:102;50565:5;50556;:14;50552:99;;50600:5;50591:14;;;;;;:::i;:::-;;;;;50634:1;50624:11;;;;50552:99;50678:5;50669;:14;50665:99;;50713:5;50704:14;;;;;;:::i;:::-;;;;;50747:1;50737:11;;;;50665:99;50791:5;50782;:14;50778:99;;50826:5;50817:14;;;;;;:::i;:::-;;;;;50860:1;50850:11;;;;50778:99;50904:5;50895;:14;50891:66;;50940:1;50930:11;;;;50891:66;50985:6;50978:13;;;50077:922;;;:::o;5143:195::-;5200:7;5237:17;5228:26;;:5;:26;;5220:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;5324:5;5309:21;;5143:195;;;:::o;57888:904::-;58010:7;58019;58039:11;58053:4;:11;;;;58039:25;;58087:1;58081:3;:7;58077:708;;;58158:22;58183:28;58197:4;58209:1;58203:3;:7;;;;:::i;:::-;58183:13;:28::i;:::-;58158:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58310:3;58289:24;;:4;:17;;;:24;;;;58281:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;58429:3;58408:24;;:4;:17;;;:24;;;58404:206;;58491:5;58453:28;58467:4;58479:1;58473:3;:7;;;;:::i;:::-;58453:13;:28::i;:::-;:35;;;:43;;;;;;;;;;;;;;;;;;58404:206;;;58537:4;58547:46;;;;;;;;58573:3;58547:46;;;;;;58586:5;58547:46;;;;;58537:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58404:206;58632:4;:11;;;58645:5;58624:27;;;;;;;;58077:708;58684:4;58694:46;;;;;;;;58720:3;58694:46;;;;;;58733:5;58694:46;;;;;58684:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58764:1;58767:5;58756:17;;;;;57888:904;;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:619::-;4967:6;4975;4983;5032:2;5020:9;5011:7;5007:23;5003:32;5000:119;;;5038:79;;:::i;:::-;5000:119;5158:1;5183:53;5228:7;5219:6;5208:9;5204:22;5183:53;:::i;:::-;5173:63;;5129:117;5285:2;5311:53;5356:7;5347:6;5336:9;5332:22;5311:53;:::i;:::-;5301:63;;5256:118;5413:2;5439:53;5484:7;5475:6;5464:9;5460:22;5439:53;:::i;:::-;5429:63;;5384:118;4890:619;;;;;:::o;5515:77::-;5552:7;5581:5;5570:16;;5515:77;;;:::o;5598:118::-;5685:24;5703:5;5685:24;:::i;:::-;5680:3;5673:37;5598:118;;:::o;5722:222::-;5815:4;5853:2;5842:9;5838:18;5830:26;;5866:71;5934:1;5923:9;5919:17;5910:6;5866:71;:::i;:::-;5722:222;;;;:::o;5950:118::-;6037:24;6055:5;6037:24;:::i;:::-;6032:3;6025:37;5950:118;;:::o;6074:222::-;6167:4;6205:2;6194:9;6190:18;6182:26;;6218:71;6286:1;6275:9;6271:17;6262:6;6218:71;:::i;:::-;6074:222;;;;:::o;6302:329::-;6361:6;6410:2;6398:9;6389:7;6385:23;6381:32;6378:119;;;6416:79;;:::i;:::-;6378:119;6536:1;6561:53;6606:7;6597:6;6586:9;6582:22;6561:53;:::i;:::-;6551:63;;6507:117;6302:329;;;;:::o;6637:116::-;6707:21;6722:5;6707:21;:::i;:::-;6700:5;6697:32;6687:60;;6743:1;6740;6733:12;6687:60;6637:116;:::o;6759:133::-;6802:5;6840:6;6827:20;6818:29;;6856:30;6880:5;6856:30;:::i;:::-;6759:133;;;;:::o;6898:468::-;6963:6;6971;7020:2;7008:9;6999:7;6995:23;6991:32;6988:119;;;7026:79;;:::i;:::-;6988:119;7146:1;7171:53;7216:7;7207:6;7196:9;7192:22;7171:53;:::i;:::-;7161:63;;7117:117;7273:2;7299:50;7341:7;7332:6;7321:9;7317:22;7299:50;:::i;:::-;7289:60;;7244:115;6898:468;;;;;:::o;7372:117::-;7481:1;7478;7471:12;7495:117;7604:1;7601;7594:12;7618:180;7666:77;7663:1;7656:88;7763:4;7760:1;7753:15;7787:4;7784:1;7777:15;7804:281;7887:27;7909:4;7887:27;:::i;:::-;7879:6;7875:40;8017:6;8005:10;8002:22;7981:18;7969:10;7966:34;7963:62;7960:88;;;8028:18;;:::i;:::-;7960:88;8068:10;8064:2;8057:22;7847:238;7804:281;;:::o;8091:129::-;8125:6;8152:20;;:::i;:::-;8142:30;;8181:33;8209:4;8201:6;8181:33;:::i;:::-;8091:129;;;:::o;8226:307::-;8287:4;8377:18;8369:6;8366:30;8363:56;;;8399:18;;:::i;:::-;8363:56;8437:29;8459:6;8437:29;:::i;:::-;8429:37;;8521:4;8515;8511:15;8503:23;;8226:307;;;:::o;8539:146::-;8636:6;8631:3;8626;8613:30;8677:1;8668:6;8663:3;8659:16;8652:27;8539:146;;;:::o;8691:423::-;8768:5;8793:65;8809:48;8850:6;8809:48;:::i;:::-;8793:65;:::i;:::-;8784:74;;8881:6;8874:5;8867:21;8919:4;8912:5;8908:16;8957:3;8948:6;8943:3;8939:16;8936:25;8933:112;;;8964:79;;:::i;:::-;8933:112;9054:54;9101:6;9096:3;9091;9054:54;:::i;:::-;8774:340;8691:423;;;;;:::o;9133:338::-;9188:5;9237:3;9230:4;9222:6;9218:17;9214:27;9204:122;;9245:79;;:::i;:::-;9204:122;9362:6;9349:20;9387:78;9461:3;9453:6;9446:4;9438:6;9434:17;9387:78;:::i;:::-;9378:87;;9194:277;9133:338;;;;:::o;9477:943::-;9572:6;9580;9588;9596;9645:3;9633:9;9624:7;9620:23;9616:33;9613:120;;;9652:79;;:::i;:::-;9613:120;9772:1;9797:53;9842:7;9833:6;9822:9;9818:22;9797:53;:::i;:::-;9787:63;;9743:117;9899:2;9925:53;9970:7;9961:6;9950:9;9946:22;9925:53;:::i;:::-;9915:63;;9870:118;10027:2;10053:53;10098:7;10089:6;10078:9;10074:22;10053:53;:::i;:::-;10043:63;;9998:118;10183:2;10172:9;10168:18;10155:32;10214:18;10206:6;10203:30;10200:117;;;10236:79;;:::i;:::-;10200:117;10341:62;10395:7;10386:6;10375:9;10371:22;10341:62;:::i;:::-;10331:72;;10126:287;9477:943;;;;;;;:::o;10426:86::-;10461:7;10501:4;10494:5;10490:16;10479:27;;10426:86;;;:::o;10518:118::-;10589:22;10605:5;10589:22;:::i;:::-;10582:5;10579:33;10569:61;;10626:1;10623;10616:12;10569:61;10518:118;:::o;10642:135::-;10686:5;10724:6;10711:20;10702:29;;10740:31;10765:5;10740:31;:::i;:::-;10642:135;;;;:::o;10783:122::-;10856:24;10874:5;10856:24;:::i;:::-;10849:5;10846:35;10836:63;;10895:1;10892;10885:12;10836:63;10783:122;:::o;10911:139::-;10957:5;10995:6;10982:20;10973:29;;11011:33;11038:5;11011:33;:::i;:::-;10911:139;;;;:::o;11056:1053::-;11158:6;11166;11174;11182;11190;11198;11247:3;11235:9;11226:7;11222:23;11218:33;11215:120;;;11254:79;;:::i;:::-;11215:120;11374:1;11399:53;11444:7;11435:6;11424:9;11420:22;11399:53;:::i;:::-;11389:63;;11345:117;11501:2;11527:53;11572:7;11563:6;11552:9;11548:22;11527:53;:::i;:::-;11517:63;;11472:118;11629:2;11655:53;11700:7;11691:6;11680:9;11676:22;11655:53;:::i;:::-;11645:63;;11600:118;11757:2;11783:51;11826:7;11817:6;11806:9;11802:22;11783:51;:::i;:::-;11773:61;;11728:116;11883:3;11910:53;11955:7;11946:6;11935:9;11931:22;11910:53;:::i;:::-;11900:63;;11854:119;12012:3;12039:53;12084:7;12075:6;12064:9;12060:22;12039:53;:::i;:::-;12029:63;;11983:119;11056:1053;;;;;;;;:::o;12115:308::-;12177:4;12267:18;12259:6;12256:30;12253:56;;;12289:18;;:::i;:::-;12253:56;12327:29;12349:6;12327:29;:::i;:::-;12319:37;;12411:4;12405;12401:15;12393:23;;12115:308;;;:::o;12429:425::-;12507:5;12532:66;12548:49;12590:6;12548:49;:::i;:::-;12532:66;:::i;:::-;12523:75;;12621:6;12614:5;12607:21;12659:4;12652:5;12648:16;12697:3;12688:6;12683:3;12679:16;12676:25;12673:112;;;12704:79;;:::i;:::-;12673:112;12794:54;12841:6;12836:3;12831;12794:54;:::i;:::-;12513:341;12429:425;;;;;:::o;12874:340::-;12930:5;12979:3;12972:4;12964:6;12960:17;12956:27;12946:122;;12987:79;;:::i;:::-;12946:122;13104:6;13091:20;13129:79;13204:3;13196:6;13189:4;13181:6;13177:17;13129:79;:::i;:::-;13120:88;;12936:278;12874:340;;;;:::o;13220:654::-;13298:6;13306;13355:2;13343:9;13334:7;13330:23;13326:32;13323:119;;;13361:79;;:::i;:::-;13323:119;13481:1;13506:53;13551:7;13542:6;13531:9;13527:22;13506:53;:::i;:::-;13496:63;;13452:117;13636:2;13625:9;13621:18;13608:32;13667:18;13659:6;13656:30;13653:117;;;13689:79;;:::i;:::-;13653:117;13794:63;13849:7;13840:6;13829:9;13825:22;13794:63;:::i;:::-;13784:73;;13579:288;13220:654;;;;;:::o;13880:474::-;13948:6;13956;14005:2;13993:9;13984:7;13980:23;13976:32;13973:119;;;14011:79;;:::i;:::-;13973:119;14131:1;14156:53;14201:7;14192:6;14181:9;14177:22;14156:53;:::i;:::-;14146:63;;14102:117;14258:2;14284:53;14329:7;14320:6;14309:9;14305:22;14284:53;:::i;:::-;14274:63;;14229:118;13880:474;;;;;:::o;14360:180::-;14408:77;14405:1;14398:88;14505:4;14502:1;14495:15;14529:4;14526:1;14519:15;14546:320;14590:6;14627:1;14621:4;14617:12;14607:22;;14674:1;14668:4;14664:12;14695:18;14685:81;;14751:4;14743:6;14739:17;14729:27;;14685:81;14813:2;14805:6;14802:14;14782:18;14779:38;14776:84;;14832:18;;:::i;:::-;14776:84;14597:269;14546:320;;;:::o;14872:220::-;15012:34;15008:1;15000:6;14996:14;14989:58;15081:3;15076:2;15068:6;15064:15;15057:28;14872:220;:::o;15098:366::-;15240:3;15261:67;15325:2;15320:3;15261:67;:::i;:::-;15254:74;;15337:93;15426:3;15337:93;:::i;:::-;15455:2;15450:3;15446:12;15439:19;;15098:366;;;:::o;15470:419::-;15636:4;15674:2;15663:9;15659:18;15651:26;;15723:9;15717:4;15713:20;15709:1;15698:9;15694:17;15687:47;15751:131;15877:4;15751:131;:::i;:::-;15743:139;;15470:419;;;:::o;15895:248::-;16035:34;16031:1;16023:6;16019:14;16012:58;16104:31;16099:2;16091:6;16087:15;16080:56;15895:248;:::o;16149:366::-;16291:3;16312:67;16376:2;16371:3;16312:67;:::i;:::-;16305:74;;16388:93;16477:3;16388:93;:::i;:::-;16506:2;16501:3;16497:12;16490:19;;16149:366;;;:::o;16521:419::-;16687:4;16725:2;16714:9;16710:18;16702:26;;16774:9;16768:4;16764:20;16760:1;16749:9;16745:17;16738:47;16802:131;16928:4;16802:131;:::i;:::-;16794:139;;16521:419;;;:::o;16946:232::-;17086:34;17082:1;17074:6;17070:14;17063:58;17155:15;17150:2;17142:6;17138:15;17131:40;16946:232;:::o;17184:366::-;17326:3;17347:67;17411:2;17406:3;17347:67;:::i;:::-;17340:74;;17423:93;17512:3;17423:93;:::i;:::-;17541:2;17536:3;17532:12;17525:19;;17184:366;;;:::o;17556:419::-;17722:4;17760:2;17749:9;17745:18;17737:26;;17809:9;17803:4;17799:20;17795:1;17784:9;17780:17;17773:47;17837:131;17963:4;17837:131;:::i;:::-;17829:139;;17556:419;;;:::o;17981:174::-;18121:26;18117:1;18109:6;18105:14;18098:50;17981:174;:::o;18161:366::-;18303:3;18324:67;18388:2;18383:3;18324:67;:::i;:::-;18317:74;;18400:93;18489:3;18400:93;:::i;:::-;18518:2;18513:3;18509:12;18502:19;;18161:366;;;:::o;18533:419::-;18699:4;18737:2;18726:9;18722:18;18714:26;;18786:9;18780:4;18776:20;18772:1;18761:9;18757:17;18750:47;18814:131;18940:4;18814:131;:::i;:::-;18806:139;;18533:419;;;:::o;18958:228::-;19098:34;19094:1;19086:6;19082:14;19075:58;19167:11;19162:2;19154:6;19150:15;19143:36;18958:228;:::o;19192:366::-;19334:3;19355:67;19419:2;19414:3;19355:67;:::i;:::-;19348:74;;19431:93;19520:3;19431:93;:::i;:::-;19549:2;19544:3;19540:12;19533:19;;19192:366;;;:::o;19564:419::-;19730:4;19768:2;19757:9;19753:18;19745:26;;19817:9;19811:4;19807:20;19803:1;19792:9;19788:17;19781:47;19845:131;19971:4;19845:131;:::i;:::-;19837:139;;19564:419;;;:::o;19989:176::-;20129:28;20125:1;20117:6;20113:14;20106:52;19989:176;:::o;20171:366::-;20313:3;20334:67;20398:2;20393:3;20334:67;:::i;:::-;20327:74;;20410:93;20499:3;20410:93;:::i;:::-;20528:2;20523:3;20519:12;20512:19;;20171:366;;;:::o;20543:419::-;20709:4;20747:2;20736:9;20732:18;20724:26;;20796:9;20790:4;20786:20;20782:1;20771:9;20767:17;20760:47;20824:131;20950:4;20824:131;:::i;:::-;20816:139;;20543:419;;;:::o;20968:174::-;21108:26;21104:1;21096:6;21092:14;21085:50;20968:174;:::o;21148:366::-;21290:3;21311:67;21375:2;21370:3;21311:67;:::i;:::-;21304:74;;21387:93;21476:3;21387:93;:::i;:::-;21505:2;21500:3;21496:12;21489:19;;21148:366;;;:::o;21520:419::-;21686:4;21724:2;21713:9;21709:18;21701:26;;21773:9;21767:4;21763:20;21759:1;21748:9;21744:17;21737:47;21801:131;21927:4;21801:131;:::i;:::-;21793:139;;21520:419;;;:::o;21945:553::-;22122:4;22160:3;22149:9;22145:19;22137:27;;22174:71;22242:1;22231:9;22227:17;22218:6;22174:71;:::i;:::-;22255:72;22323:2;22312:9;22308:18;22299:6;22255:72;:::i;:::-;22337;22405:2;22394:9;22390:18;22381:6;22337:72;:::i;:::-;22419;22487:2;22476:9;22472:18;22463:6;22419:72;:::i;:::-;21945:553;;;;;;;:::o;22504:170::-;22644:22;22640:1;22632:6;22628:14;22621:46;22504:170;:::o;22680:366::-;22822:3;22843:67;22907:2;22902:3;22843:67;:::i;:::-;22836:74;;22919:93;23008:3;22919:93;:::i;:::-;23037:2;23032:3;23028:12;23021:19;;22680:366;;;:::o;23052:419::-;23218:4;23256:2;23245:9;23241:18;23233:26;;23305:9;23299:4;23295:20;23291:1;23280:9;23276:17;23269:47;23333:131;23459:4;23333:131;:::i;:::-;23325:139;;23052:419;;;:::o;23477:225::-;23617:34;23613:1;23605:6;23601:14;23594:58;23686:8;23681:2;23673:6;23669:15;23662:33;23477:225;:::o;23708:366::-;23850:3;23871:67;23935:2;23930:3;23871:67;:::i;:::-;23864:74;;23947:93;24036:3;23947:93;:::i;:::-;24065:2;24060:3;24056:12;24049:19;;23708:366;;;:::o;24080:419::-;24246:4;24284:2;24273:9;24269:18;24261:26;;24333:9;24327:4;24323:20;24319:1;24308:9;24304:17;24297:47;24361:131;24487:4;24361:131;:::i;:::-;24353:139;;24080:419;;;:::o;24505:224::-;24645:34;24641:1;24633:6;24629:14;24622:58;24714:7;24709:2;24701:6;24697:15;24690:32;24505:224;:::o;24735:366::-;24877:3;24898:67;24962:2;24957:3;24898:67;:::i;:::-;24891:74;;24974:93;25063:3;24974:93;:::i;:::-;25092:2;25087:3;25083:12;25076:19;;24735:366;;;:::o;25107:419::-;25273:4;25311:2;25300:9;25296:18;25288:26;;25360:9;25354:4;25350:20;25346:1;25335:9;25331:17;25324:47;25388:131;25514:4;25388:131;:::i;:::-;25380:139;;25107:419;;;:::o;25532:223::-;25672:34;25668:1;25660:6;25656:14;25649:58;25741:6;25736:2;25728:6;25724:15;25717:31;25532:223;:::o;25761:366::-;25903:3;25924:67;25988:2;25983:3;25924:67;:::i;:::-;25917:74;;26000:93;26089:3;26000:93;:::i;:::-;26118:2;26113:3;26109:12;26102:19;;25761:366;;;:::o;26133:419::-;26299:4;26337:2;26326:9;26322:18;26314:26;;26386:9;26380:4;26376:20;26372:1;26361:9;26357:17;26350:47;26414:131;26540:4;26414:131;:::i;:::-;26406:139;;26133:419;;;:::o;26558:182::-;26698:34;26694:1;26686:6;26682:14;26675:58;26558:182;:::o;26746:366::-;26888:3;26909:67;26973:2;26968:3;26909:67;:::i;:::-;26902:74;;26985:93;27074:3;26985:93;:::i;:::-;27103:2;27098:3;27094:12;27087:19;;26746:366;;;:::o;27118:419::-;27284:4;27322:2;27311:9;27307:18;27299:26;;27371:9;27365:4;27361:20;27357:1;27346:9;27342:17;27335:47;27399:131;27525:4;27399:131;:::i;:::-;27391:139;;27118:419;;;:::o;27543:180::-;27591:77;27588:1;27581:88;27688:4;27685:1;27678:15;27712:4;27709:1;27702:15;27729:194;27769:4;27789:20;27807:1;27789:20;:::i;:::-;27784:25;;27823:20;27841:1;27823:20;:::i;:::-;27818:25;;27867:1;27864;27860:9;27852:17;;27891:1;27885:4;27882:11;27879:37;;;27896:18;;:::i;:::-;27879:37;27729:194;;;;:::o;27929:191::-;27969:3;27988:20;28006:1;27988:20;:::i;:::-;27983:25;;28022:20;28040:1;28022:20;:::i;:::-;28017:25;;28065:1;28062;28058:9;28051:16;;28086:3;28083:1;28080:10;28077:36;;;28093:18;;:::i;:::-;28077:36;27929:191;;;;:::o;28126:182::-;28266:34;28262:1;28254:6;28250:14;28243:58;28126:182;:::o;28314:366::-;28456:3;28477:67;28541:2;28536:3;28477:67;:::i;:::-;28470:74;;28553:93;28642:3;28553:93;:::i;:::-;28671:2;28666:3;28662:12;28655:19;;28314:366;;;:::o;28686:419::-;28852:4;28890:2;28879:9;28875:18;28867:26;;28939:9;28933:4;28929:20;28925:1;28914:9;28910:17;28903:47;28967:131;29093:4;28967:131;:::i;:::-;28959:139;;28686:419;;;:::o;29111:175::-;29251:27;29247:1;29239:6;29235:14;29228:51;29111:175;:::o;29292:366::-;29434:3;29455:67;29519:2;29514:3;29455:67;:::i;:::-;29448:74;;29531:93;29620:3;29531:93;:::i;:::-;29649:2;29644:3;29640:12;29633:19;;29292:366;;;:::o;29664:419::-;29830:4;29868:2;29857:9;29853:18;29845:26;;29917:9;29911:4;29907:20;29903:1;29892:9;29888:17;29881:47;29945:131;30071:4;29945:131;:::i;:::-;29937:139;;29664:419;;;:::o;30089:237::-;30229:34;30225:1;30217:6;30213:14;30206:58;30298:20;30293:2;30285:6;30281:15;30274:45;30089:237;:::o;30332:366::-;30474:3;30495:67;30559:2;30554:3;30495:67;:::i;:::-;30488:74;;30571:93;30660:3;30571:93;:::i;:::-;30689:2;30684:3;30680:12;30673:19;;30332:366;;;:::o;30704:419::-;30870:4;30908:2;30897:9;30893:18;30885:26;;30957:9;30951:4;30947:20;30943:1;30932:9;30928:17;30921:47;30985:131;31111:4;30985:131;:::i;:::-;30977:139;;30704:419;;;:::o;31129:148::-;31231:11;31268:3;31253:18;;31129:148;;;;:::o;31283:390::-;31389:3;31417:39;31450:5;31417:39;:::i;:::-;31472:89;31554:6;31549:3;31472:89;:::i;:::-;31465:96;;31570:65;31628:6;31623:3;31616:4;31609:5;31605:16;31570:65;:::i;:::-;31660:6;31655:3;31651:16;31644:23;;31393:280;31283:390;;;;:::o;31679:435::-;31859:3;31881:95;31972:3;31963:6;31881:95;:::i;:::-;31874:102;;31993:95;32084:3;32075:6;31993:95;:::i;:::-;31986:102;;32105:3;32098:10;;31679:435;;;;;:::o;32120:233::-;32260:34;32256:1;32248:6;32244:14;32237:58;32329:16;32324:2;32316:6;32312:15;32305:41;32120:233;:::o;32359:366::-;32501:3;32522:67;32586:2;32581:3;32522:67;:::i;:::-;32515:74;;32598:93;32687:3;32598:93;:::i;:::-;32716:2;32711:3;32707:12;32700:19;;32359:366;;;:::o;32731:419::-;32897:4;32935:2;32924:9;32920:18;32912:26;;32984:9;32978:4;32974:20;32970:1;32959:9;32955:17;32948:47;33012:131;33138:4;33012:131;:::i;:::-;33004:139;;32731:419;;;:::o;33156:141::-;33205:4;33228:3;33220:11;;33251:3;33248:1;33241:14;33285:4;33282:1;33272:18;33264:26;;33156:141;;;:::o;33303:93::-;33340:6;33387:2;33382;33375:5;33371:14;33367:23;33357:33;;33303:93;;;:::o;33402:107::-;33446:8;33496:5;33490:4;33486:16;33465:37;;33402:107;;;;:::o;33515:393::-;33584:6;33634:1;33622:10;33618:18;33657:97;33687:66;33676:9;33657:97;:::i;:::-;33775:39;33805:8;33794:9;33775:39;:::i;:::-;33763:51;;33847:4;33843:9;33836:5;33832:21;33823:30;;33896:4;33886:8;33882:19;33875:5;33872:30;33862:40;;33591:317;;33515:393;;;;;:::o;33914:60::-;33942:3;33963:5;33956:12;;33914:60;;;:::o;33980:142::-;34030:9;34063:53;34081:34;34090:24;34108:5;34090:24;:::i;:::-;34081:34;:::i;:::-;34063:53;:::i;:::-;34050:66;;33980:142;;;:::o;34128:75::-;34171:3;34192:5;34185:12;;34128:75;;;:::o;34209:269::-;34319:39;34350:7;34319:39;:::i;:::-;34380:91;34429:41;34453:16;34429:41;:::i;:::-;34421:6;34414:4;34408:11;34380:91;:::i;:::-;34374:4;34367:105;34285:193;34209:269;;;:::o;34484:73::-;34529:3;34484:73;:::o;34563:189::-;34640:32;;:::i;:::-;34681:65;34739:6;34731;34725:4;34681:65;:::i;:::-;34616:136;34563:189;;:::o;34758:186::-;34818:120;34835:3;34828:5;34825:14;34818:120;;;34889:39;34926:1;34919:5;34889:39;:::i;:::-;34862:1;34855:5;34851:13;34842:22;;34818:120;;;34758:186;;:::o;34950:543::-;35051:2;35046:3;35043:11;35040:446;;;35085:38;35117:5;35085:38;:::i;:::-;35169:29;35187:10;35169:29;:::i;:::-;35159:8;35155:44;35352:2;35340:10;35337:18;35334:49;;;35373:8;35358:23;;35334:49;35396:80;35452:22;35470:3;35452:22;:::i;:::-;35442:8;35438:37;35425:11;35396:80;:::i;:::-;35055:431;;35040:446;34950:543;;;:::o;35499:117::-;35553:8;35603:5;35597:4;35593:16;35572:37;;35499:117;;;;:::o;35622:169::-;35666:6;35699:51;35747:1;35743:6;35735:5;35732:1;35728:13;35699:51;:::i;:::-;35695:56;35780:4;35774;35770:15;35760:25;;35673:118;35622:169;;;;:::o;35796:295::-;35872:4;36018:29;36043:3;36037:4;36018:29;:::i;:::-;36010:37;;36080:3;36077:1;36073:11;36067:4;36064:21;36056:29;;35796:295;;;;:::o;36096:1395::-;36213:37;36246:3;36213:37;:::i;:::-;36315:18;36307:6;36304:30;36301:56;;;36337:18;;:::i;:::-;36301:56;36381:38;36413:4;36407:11;36381:38;:::i;:::-;36466:67;36526:6;36518;36512:4;36466:67;:::i;:::-;36560:1;36584:4;36571:17;;36616:2;36608:6;36605:14;36633:1;36628:618;;;;37290:1;37307:6;37304:77;;;37356:9;37351:3;37347:19;37341:26;37332:35;;37304:77;37407:67;37467:6;37460:5;37407:67;:::i;:::-;37401:4;37394:81;37263:222;36598:887;;36628:618;36680:4;36676:9;36668:6;36664:22;36714:37;36746:4;36714:37;:::i;:::-;36773:1;36787:208;36801:7;36798:1;36795:14;36787:208;;;36880:9;36875:3;36871:19;36865:26;36857:6;36850:42;36931:1;36923:6;36919:14;36909:24;;36978:2;36967:9;36963:18;36950:31;;36824:4;36821:1;36817:12;36812:17;;36787:208;;;37023:6;37014:7;37011:19;37008:179;;;37081:9;37076:3;37072:19;37066:26;37124:48;37166:4;37158:6;37154:17;37143:9;37124:48;:::i;:::-;37116:6;37109:64;37031:156;37008:179;37233:1;37229;37221:6;37217:14;37213:22;37207:4;37200:36;36635:611;;;36598:887;;36188:1303;;;36096:1395;;:::o;37497:664::-;37702:4;37740:3;37729:9;37725:19;37717:27;;37754:71;37822:1;37811:9;37807:17;37798:6;37754:71;:::i;:::-;37835:72;37903:2;37892:9;37888:18;37879:6;37835:72;:::i;:::-;37917;37985:2;37974:9;37970:18;37961:6;37917:72;:::i;:::-;37999;38067:2;38056:9;38052:18;38043:6;37999:72;:::i;:::-;38081:73;38149:3;38138:9;38134:19;38125:6;38081:73;:::i;:::-;37497:664;;;;;;;;:::o;38167:225::-;38307:34;38303:1;38295:6;38291:14;38284:58;38376:8;38371:2;38363:6;38359:15;38352:33;38167:225;:::o;38398:366::-;38540:3;38561:67;38625:2;38620:3;38561:67;:::i;:::-;38554:74;;38637:93;38726:3;38637:93;:::i;:::-;38755:2;38750:3;38746:12;38739:19;;38398:366;;;:::o;38770:419::-;38936:4;38974:2;38963:9;38959:18;38951:26;;39023:9;39017:4;39013:20;39009:1;38998:9;38994:17;38987:47;39051:131;39177:4;39051:131;:::i;:::-;39043:139;;38770:419;;;:::o;39195:180::-;39243:77;39240:1;39233:88;39340:4;39337:1;39330:15;39364:4;39361:1;39354:15;39381:332;39502:4;39540:2;39529:9;39525:18;39517:26;;39553:71;39621:1;39610:9;39606:17;39597:6;39553:71;:::i;:::-;39634:72;39702:2;39691:9;39687:18;39678:6;39634:72;:::i;:::-;39381:332;;;;;:::o;39719:98::-;39770:6;39804:5;39798:12;39788:22;;39719:98;;;:::o;39823:168::-;39906:11;39940:6;39935:3;39928:19;39980:4;39975:3;39971:14;39956:29;;39823:168;;;;:::o;39997:373::-;40083:3;40111:38;40143:5;40111:38;:::i;:::-;40165:70;40228:6;40223:3;40165:70;:::i;:::-;40158:77;;40244:65;40302:6;40297:3;40290:4;40283:5;40279:16;40244:65;:::i;:::-;40334:29;40356:6;40334:29;:::i;:::-;40329:3;40325:39;40318:46;;40087:283;39997:373;;;;:::o;40376:640::-;40571:4;40609:3;40598:9;40594:19;40586:27;;40623:71;40691:1;40680:9;40676:17;40667:6;40623:71;:::i;:::-;40704:72;40772:2;40761:9;40757:18;40748:6;40704:72;:::i;:::-;40786;40854:2;40843:9;40839:18;40830:6;40786:72;:::i;:::-;40905:9;40899:4;40895:20;40890:2;40879:9;40875:18;40868:48;40933:76;41004:4;40995:6;40933:76;:::i;:::-;40925:84;;40376:640;;;;;;;:::o;41022:141::-;41078:5;41109:6;41103:13;41094:22;;41125:32;41151:5;41125:32;:::i;:::-;41022:141;;;;:::o;41169:349::-;41238:6;41287:2;41275:9;41266:7;41262:23;41258:32;41255:119;;;41293:79;;:::i;:::-;41255:119;41413:1;41438:63;41493:7;41484:6;41473:9;41469:22;41438:63;:::i;:::-;41428:73;;41384:127;41169:349;;;;:::o;41524:214::-;41664:66;41660:1;41652:6;41648:14;41641:90;41524:214;:::o;41744:400::-;41904:3;41925:84;42007:1;42002:3;41925:84;:::i;:::-;41918:91;;42018:93;42107:3;42018:93;:::i;:::-;42136:1;42131:3;42127:11;42120:18;;41744:400;;;:::o;42150:79::-;42189:7;42218:5;42207:16;;42150:79;;;:::o;42235:157::-;42340:45;42360:24;42378:5;42360:24;:::i;:::-;42340:45;:::i;:::-;42335:3;42328:58;42235:157;;:::o;42398:663::-;42639:3;42661:148;42805:3;42661:148;:::i;:::-;42654:155;;42819:75;42890:3;42881:6;42819:75;:::i;:::-;42919:2;42914:3;42910:12;42903:19;;42932:75;43003:3;42994:6;42932:75;:::i;:::-;43032:2;43027:3;43023:12;43016:19;;43052:3;43045:10;;42398:663;;;;;:::o;43067:112::-;43150:22;43166:5;43150:22;:::i;:::-;43145:3;43138:35;43067:112;;:::o;43185:545::-;43358:4;43396:3;43385:9;43381:19;43373:27;;43410:71;43478:1;43467:9;43463:17;43454:6;43410:71;:::i;:::-;43491:68;43555:2;43544:9;43540:18;43531:6;43491:68;:::i;:::-;43569:72;43637:2;43626:9;43622:18;43613:6;43569:72;:::i;:::-;43651;43719:2;43708:9;43704:18;43695:6;43651:72;:::i;:::-;43185:545;;;;;;;:::o;43736:180::-;43784:77;43781:1;43774:88;43881:4;43878:1;43871:15;43905:4;43902:1;43895:15;43922:174;44062:26;44058:1;44050:6;44046:14;44039:50;43922:174;:::o;44102:366::-;44244:3;44265:67;44329:2;44324:3;44265:67;:::i;:::-;44258:74;;44341:93;44430:3;44341:93;:::i;:::-;44459:2;44454:3;44450:12;44443:19;;44102:366;;;:::o;44474:419::-;44640:4;44678:2;44667:9;44663:18;44655:26;;44727:9;44721:4;44717:20;44713:1;44702:9;44698:17;44691:47;44755:131;44881:4;44755:131;:::i;:::-;44747:139;;44474:419;;;:::o;44899:181::-;45039:33;45035:1;45027:6;45023:14;45016:57;44899:181;:::o;45086:366::-;45228:3;45249:67;45313:2;45308:3;45249:67;:::i;:::-;45242:74;;45325:93;45414:3;45325:93;:::i;:::-;45443:2;45438:3;45434:12;45427:19;;45086:366;;;:::o;45458:419::-;45624:4;45662:2;45651:9;45647:18;45639:26;;45711:9;45705:4;45701:20;45697:1;45686:9;45682:17;45675:47;45739:131;45865:4;45739:131;:::i;:::-;45731:139;;45458:419;;;:::o;45883:221::-;46023:34;46019:1;46011:6;46007:14;46000:58;46092:4;46087:2;46079:6;46075:15;46068:29;45883:221;:::o;46110:366::-;46252:3;46273:67;46337:2;46332:3;46273:67;:::i;:::-;46266:74;;46349:93;46438:3;46349:93;:::i;:::-;46467:2;46462:3;46458:12;46451:19;;46110:366;;;:::o;46482:419::-;46648:4;46686:2;46675:9;46671:18;46663:26;;46735:9;46729:4;46725:20;46721:1;46710:9;46706:17;46699:47;46763:131;46889:4;46763:131;:::i;:::-;46755:139;;46482:419;;;:::o;46907:185::-;46947:1;46964:20;46982:1;46964:20;:::i;:::-;46959:25;;46998:20;47016:1;46998:20;:::i;:::-;46993:25;;47037:1;47027:35;;47042:18;;:::i;:::-;47027:35;47084:1;47081;47077:9;47072:14;;46907:185;;;;:::o;47098:182::-;47238:34;47234:1;47226:6;47222:14;47215:58;47098:182;:::o;47286:366::-;47428:3;47449:67;47513:2;47508:3;47449:67;:::i;:::-;47442:74;;47525:93;47614:3;47525:93;:::i;:::-;47643:2;47638:3;47634:12;47627:19;;47286:366;;;:::o;47658:419::-;47824:4;47862:2;47851:9;47847:18;47839:26;;47911:9;47905:4;47901:20;47897:1;47886:9;47882:17;47875:47;47939:131;48065:4;47939:131;:::i;:::-;47931:139;;47658:419;;;:::o;48083:178::-;48223:30;48219:1;48211:6;48207:14;48200:54;48083:178;:::o;48267:366::-;48409:3;48430:67;48494:2;48489:3;48430:67;:::i;:::-;48423:74;;48506:93;48595:3;48506:93;:::i;:::-;48624:2;48619:3;48615:12;48608:19;;48267:366;;;:::o;48639:419::-;48805:4;48843:2;48832:9;48828:18;48820:26;;48892:9;48886:4;48882:20;48878:1;48867:9;48863:17;48856:47;48920:131;49046:4;48920:131;:::i;:::-;48912:139;;48639:419;;;:::o;49064:226::-;49204:34;49200:1;49192:6;49188:14;49181:58;49273:9;49268:2;49260:6;49256:15;49249:34;49064:226;:::o;49296:366::-;49438:3;49459:67;49523:2;49518:3;49459:67;:::i;:::-;49452:74;;49535:93;49624:3;49535:93;:::i;:::-;49653:2;49648:3;49644:12;49637:19;;49296:366;;;:::o;49668:419::-;49834:4;49872:2;49861:9;49857:18;49849:26;;49921:9;49915:4;49911:20;49907:1;49896:9;49892:17;49885:47;49949:131;50075:4;49949:131;:::i;:::-;49941:139;;49668:419;;;:::o;50093:173::-;50233:25;50229:1;50221:6;50217:14;50210:49;50093:173;:::o;50272:366::-;50414:3;50435:67;50499:2;50494:3;50435:67;:::i;:::-;50428:74;;50511:93;50600:3;50511:93;:::i;:::-;50629:2;50624:3;50620:12;50613:19;;50272:366;;;:::o;50644:419::-;50810:4;50848:2;50837:9;50833:18;50825:26;;50897:9;50891:4;50887:20;50883:1;50872:9;50868:17;50861:47;50925:131;51051:4;50925:131;:::i;:::-;50917:139;;50644:419;;;:::o

Swarm Source

ipfs://1ab0472614a8e981c825c09616f09840d3907562d4cb1b2e55504baf1ee5b241
[ 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.