ETH Price: $3,556.63 (+4.37%)

Contract

0x77512f14F308D1fE3Ab598c9b347E80c34842420
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
Cast Vote Withou...1169966072024-03-04 22:39:51106 days ago1709591991IN
0x77512f14...c34842420
0.000069 ETH0.000000270.00091589
Cast Vote1169096122024-03-02 22:20:01108 days ago1709418001IN
0x77512f14...c34842420
0.000069 ETH0.000002540.00840761
Cast Vote Withou...1167269522024-02-27 16:51:21113 days ago1709052681IN
0x77512f14...c34842420
0.000069 ETH0.000005720.01971802
Cast Vote1167268892024-02-27 16:49:15113 days ago1709052555IN
0x77512f14...c34842420
0.000069 ETH0.000007650.02160105
Cast Vote Withou...1166840492024-02-26 17:01:15114 days ago1708966875IN
0x77512f14...c34842420
0.000069 ETH0.000001270.00763239
Cast Vote Withou...1166840412024-02-26 17:00:59114 days ago1708966859IN
0x77512f14...c34842420
0.000069 ETH0.000001690.00777016
Cast Vote Withou...1166840212024-02-26 17:00:19114 days ago1708966819IN
0x77512f14...c34842420
0.000069 ETH0.000002090.00931573
Cast Vote Withou...1166839952024-02-26 16:59:27114 days ago1708966767IN
0x77512f14...c34842420
0.000069 ETH0.000002230.00941431
Cast Vote Withou...1166839742024-02-26 16:58:45114 days ago1708966725IN
0x77512f14...c34842420
0.000069 ETH0.000002290.009682
Cast Vote1166839542024-02-26 16:58:05114 days ago1708966685IN
0x77512f14...c34842420
0.000069 ETH0.000003940.01128178
Propose1166457552024-02-25 19:44:47114 days ago1708890287IN
0x77512f14...c34842420
0.00069 ETH0.000003780.00237182
Propose1166457302024-02-25 19:43:57114 days ago1708890237IN
0x77512f14...c34842420
0.00069 ETH0.000001410.00245089
Propose1166457112024-02-25 19:43:19114 days ago1708890199IN
0x77512f14...c34842420
0.00069 ETH0.000002690.00247974
Propose1166456952024-02-25 19:42:47114 days ago1708890167IN
0x77512f14...c34842420
0.00069 ETH0.000001780.00256879
Propose1166456592024-02-25 19:41:35114 days ago1708890095IN
0x77512f14...c34842420
0.00069 ETH0.000004210.00271837
Propose1166456232024-02-25 19:40:23114 days ago1708890023IN
0x77512f14...c34842420
0.00069 ETH0.000002840.00286016
Propose1166455932024-02-25 19:39:23114 days ago1708889963IN
0x77512f14...c34842420
0.00069 ETH0.000002320.00294846
Propose1166455712024-02-25 19:38:39114 days ago1708889919IN
0x77512f14...c34842420
0.00069 ETH0.000001650.00298325
Propose1166455522024-02-25 19:38:01114 days ago1708889881IN
0x77512f14...c34842420
0.00069 ETH0.000002570.00300674
Propose1166455282024-02-25 19:37:13114 days ago1708889833IN
0x77512f14...c34842420
0.00069 ETH0.000004010.00314161
0x608060401165263472024-02-23 1:24:31117 days ago1708651471IN
 Contract Creation
0 ETH0.00001350.00230883

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
1169966072024-03-04 22:39:51106 days ago1709591991
0x77512f14...c34842420
0.0000345 ETH
1169966072024-03-04 22:39:51106 days ago1709591991
0x77512f14...c34842420
0.0000345 ETH
1169096122024-03-02 22:20:01108 days ago1709418001
0x77512f14...c34842420
0.0000345 ETH
1169096122024-03-02 22:20:01108 days ago1709418001
0x77512f14...c34842420
0.0000345 ETH
1167269522024-02-27 16:51:21113 days ago1709052681
0x77512f14...c34842420
0.0000345 ETH
1167269522024-02-27 16:51:21113 days ago1709052681
0x77512f14...c34842420
0.0000345 ETH
1167268892024-02-27 16:49:15113 days ago1709052555
0x77512f14...c34842420
0.0000345 ETH
1167268892024-02-27 16:49:15113 days ago1709052555
0x77512f14...c34842420
0.0000345 ETH
1166840492024-02-26 17:01:15114 days ago1708966875
0x77512f14...c34842420
0.0000345 ETH
1166840492024-02-26 17:01:15114 days ago1708966875
0x77512f14...c34842420
0.0000345 ETH
1166840412024-02-26 17:00:59114 days ago1708966859
0x77512f14...c34842420
0.0000345 ETH
1166840412024-02-26 17:00:59114 days ago1708966859
0x77512f14...c34842420
0.0000345 ETH
1166840212024-02-26 17:00:19114 days ago1708966819
0x77512f14...c34842420
0.0000345 ETH
1166840212024-02-26 17:00:19114 days ago1708966819
0x77512f14...c34842420
0.0000345 ETH
1166839952024-02-26 16:59:27114 days ago1708966767
0x77512f14...c34842420
0.0000345 ETH
1166839952024-02-26 16:59:27114 days ago1708966767
0x77512f14...c34842420
0.0000345 ETH
1166839742024-02-26 16:58:45114 days ago1708966725
0x77512f14...c34842420
0.0000345 ETH
1166839742024-02-26 16:58:45114 days ago1708966725
0x77512f14...c34842420
0.0000345 ETH
1166839542024-02-26 16:58:05114 days ago1708966685
0x77512f14...c34842420
0.0000345 ETH
1166839542024-02-26 16:58:05114 days ago1708966685
0x77512f14...c34842420
0.0000345 ETH
1166835812024-02-26 16:45:39114 days ago1708965939
0x77512f14...c34842420
0.0000345 ETH
1166835812024-02-26 16:45:39114 days ago1708965939
0x77512f14...c34842420
0.0000345 ETH
1166835812024-02-26 16:45:39114 days ago1708965939
0x77512f14...c34842420
0.000069 ETH
1166457552024-02-25 19:44:47114 days ago1708890287
0x77512f14...c34842420
0.000345 ETH
1166457552024-02-25 19:44:47114 days ago1708890287
0x77512f14...c34842420
0.000345 ETH
View All Internal Transactions

Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xCF5F77BF...B5325e842
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Contest

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at optimistic.etherscan.io on 2024-02-21
*/

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.19;

// Forked from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/governance/Governor.sol

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

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

// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

/**
 * @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
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [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://consensys.net/diligence/blog/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.8.0/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);
        }
    }
}

// Forked from https://github.com/Anish-Agnihotri/merkle-airdrop-starter/blob/master/contracts/src/MerkleClaimERC20.sol

/// ============ Imports ============

// OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol)

/**
 * @dev These functions deal with verification of Merkle Tree proofs.
 *
 * The tree and the proofs can be generated using our
 * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
 * You will find a quickstart guide in the readme.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 * OpenZeppelin's JavaScript library generates merkle trees that are safe
 * against this attack out of the box.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Calldata version of {verify}
     *
     * _Available since v4.7._
     */
    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
        return processProofCalldata(proof, leaf) == root;
    }

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

    /**
     * @dev Calldata version of {processProof}
     *
     * _Available since v4.7._
     */
    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            computedHash = _hashPair(computedHash, proof[i]);
        }
        return computedHash;
    }

    /**
     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by
     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerify(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProof(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Calldata version of {multiProofVerify}
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function multiProofVerifyCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32 root,
        bytes32[] memory leaves
    ) internal pure returns (bool) {
        return processMultiProofCalldata(proof, proofFlags, leaves) == root;
    }

    /**
     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
     * respectively.
     *
     * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
     *
     * _Available since v4.7._
     */
    function processMultiProof(
        bytes32[] memory proof,
        bool[] memory proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            require(proofPos == proofLen, "MerkleProof: invalid multiproof");
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    /**
     * @dev Calldata version of {processMultiProof}.
     *
     * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details.
     *
     * _Available since v4.7._
     */
    function processMultiProofCalldata(
        bytes32[] calldata proof,
        bool[] calldata proofFlags,
        bytes32[] memory leaves
    ) internal pure returns (bytes32 merkleRoot) {
        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
        // the merkle tree.
        uint256 leavesLen = leaves.length;
        uint256 proofLen = proof.length;
        uint256 totalHashes = proofFlags.length;

        // Check proof validity.
        require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof");

        // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
        bytes32[] memory hashes = new bytes32[](totalHashes);
        uint256 leafPos = 0;
        uint256 hashPos = 0;
        uint256 proofPos = 0;
        // At each step, we compute the next hash using two values:
        // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
        //   get the next hash.
        // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
        //   `proof` array.
        for (uint256 i = 0; i < totalHashes; i++) {
            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
            bytes32 b = proofFlags[i]
                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
                : proof[proofPos++];
            hashes[i] = _hashPair(a, b);
        }

        if (totalHashes > 0) {
            require(proofPos == proofLen, "MerkleProof: invalid multiproof");
            unchecked {
                return hashes[totalHashes - 1];
            }
        } else if (leavesLen > 0) {
            return leaves[0];
        } else {
            return proof[0];
        }
    }

    function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
        return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}
 // OZ: MerkleProof

/// @title GovernorMerkleVotes
abstract contract GovernorMerkleVotes {
    /// ============ Immutable storage ============

    /// @notice Participant inclusion roots
    bytes32 public submissionMerkleRoot;
    bytes32 public votingMerkleRoot;

    /// ============ Errors ============

    /// @notice Thrown if address/amount are not part of Merkle tree
    error NotInMerkle();

    /// ============ Constructor ============

    /// @notice Creates a new GovernorMerkleVotes contract
    /// @param _submissionMerkleRoot of participants
    /// @param _votingMerkleRoot of participants
    constructor(bytes32 _submissionMerkleRoot, bytes32 _votingMerkleRoot) {
        submissionMerkleRoot = _submissionMerkleRoot; // Update root
        votingMerkleRoot = _votingMerkleRoot; // Update root
    }

    /// ============ Functions ============

    /// @notice Allows checking of proofs for an address
    /// @param addressToCheck address of participant
    /// @param amount to check that the participant has the correct amount
    /// @param proof merkle proof to prove address and amount are in tree
    /// @param voting true if this is for a voting proof, false if this is for a submission proof
    function checkProof(address addressToCheck, uint256 amount, bytes32[] calldata proof, bool voting)
        public
        view
        returns (bool verified)
    {
        // Verify merkle proof, or revert if not in tree
        bytes32 leaf = keccak256(abi.encodePacked(addressToCheck, amount));
        bool isValidLeaf = voting
            ? MerkleProof.verify(proof, votingMerkleRoot, leaf)
            : MerkleProof.verify(proof, submissionMerkleRoot, leaf);
        if (!isValidLeaf) revert NotInMerkle();
        return true;
    }
}

/**
 * @dev Logic for sorting and ranking.
 */
abstract contract GovernorSorting {
    // TLDR: This code maintains a sorted array.

    // Because of the array rule below, the actual number of rankings that this contract will be able to track is determined by three things:
    //      - RANK_LIMIT
    //      - Woulda Beens (WBs)
    //          The number of would-be ranked proposals (at the end of the contest if rankings were counted
    //          without taking out deleted proposals) within the limit that are deleted and do not have other, non-deleted proposals
    //          with the same amounts of votes/that are tied with them.
    //      - To Tied or Deleted (TTDs), or to a previous TTD
    //          The number of times a proposal's newValue goes into an index to tie it; an index that is already tied; an index that was last deleted;
    //          or an index that wasn't garbage collected because it went to either one of last three cases or an index that also wasn't garbage
    //          collected because of the same recursive logic, from a ranking that was in the tracked rankings at the time that vote was cast.
    //
    // The equation to calcluate how many rankings this contract will actually be able to track is:
    // # of rankings GovernorSorting can track for a given contest = RANK_LIMIT - WBs - TTDs
    //
    // With this in mind, it is strongly reccomended to set RANK_LIMIT sufficiently high to create a buffer for
    // WBs and TTDs that may occur in your contest. The thing to consider with regard to making it too high is just
    // that it is more gas for users on average the higher that RANK_LIMIT is set.

    uint256 public sortingEnabled; // Either 0 for false or 1 for true
    uint256 public rankLimit; // RULE: Cannot be 0

    // RULE: array length can never end lower than it started a transaction, otherwise erroneous ranking can happen
    uint256[] public sortedRanks; // value is forVotes counts, has the constraint of no duplicate values.

    constructor(uint256 sortingEnabled_, uint256 rankLimit_) {
        sortingEnabled = sortingEnabled_;
        rankLimit = rankLimit_;
    }

    /**
     * @dev See {GovernorCountingSimple-getNumProposalsWithThisManyForVotes}.
     */
    function getNumProposalsWithThisManyForVotes(uint256 forVotes) public view virtual returns (uint256 count);

    /**
     * @dev Get the sortedRanks array.
     */
    function getSortedRanks() public view returns (uint256[] memory sortedRanksArray) {
        return sortedRanks;
    }

    /**
     * @dev Insert a new value into sortedRanks (this function is strictly O(n) or better).
     *      We know at this point that the idx where it should go is in [0, sortedRanks.length - 1].
     */
    function _insertRank(
        uint256 oldValue,
        uint256 newValue,
        uint256 sortedRanksLength,
        uint256[] memory sortedRanksMemVar
    ) internal {
        // find the index to insert newValue at
        uint256 insertingIndex;
        for (uint256 index = 0; index < sortedRanksLength; index++) {
            // is this value already in the array? (is this a TTD or to a previous TTD?)
            if (newValue == sortedRanksMemVar[index]) {
                // if so, we don't need to insert anything and the oldValue of this doesn't get cleaned up
                return;
            }

            if (newValue > sortedRanksMemVar[index]) {
                insertingIndex = index;
                break;
            }
        }

        // are we checking for the oldValue?
        bool checkForOldValue = (oldValue > 0) && (getNumProposalsWithThisManyForVotes(oldValue) == 0); // if there are props left with oldValue votes, we don't want to remove it
        bool haveFoundOldValue = false;

        // DO ANY SHIFTING? - we do not need to if 1. if we're checking for oldValue and 2. oldValue is at insertingIndex - if both of those are the case, then we don't need to update anything besides insertingIndex.
        if (!(checkForOldValue && (sortedRanksMemVar[insertingIndex] == oldValue))) {
            // DO SHIFTING FROM (insertingIndex, sortedRanksLength)?
            //      - if insertingIndex == sortedRanksLength - 1, then there's nothing after it to shift down.
            //      - also if this is the case + oldValue's not at insertingIndex, then don't need to worry about oldValue bc it's not in the array.
            if (!(insertingIndex == sortedRanksLength - 1)) {
                // SHIFT UNTIL/IF YOU FIND OLD VALUE IN THE RANGE (insertingIndex, sortedRanksLength) - go through and shift everything down until/if we hit oldValue.
                // if we hit the limit then the last item will just be dropped).
                for (uint256 index = insertingIndex + 1; index < sortedRanksLength; index++) {
                    sortedRanks[index] = sortedRanksMemVar[index - 1];

                    // STOP ONCE YOU FIND OLD VALUE - if I'm looking for it, once I shift a value into the index oldValue was in (if it's in here) I can stop!
                    if (checkForOldValue && (sortedRanksMemVar[index] == oldValue)) {
                        haveFoundOldValue = true;
                        break;
                    }
                }
            }

            // SHIFT INTO NEW INDEX? - if we didn't run into oldValue and we wouldn't be trying to shift into index RANK_LIMIT, then
            // go ahead and shift what was in sortedRanksLength - 1 into the next idx
            if (!haveFoundOldValue && (sortedRanksLength < rankLimit)) {
                sortedRanks.push(sortedRanksMemVar[sortedRanksLength - 1]);
            }
        }

        // SET INSERTING IDX - now that everything's been accounted for, let's correctly set sortedRanks[insertingIndex]
        sortedRanks[insertingIndex] = newValue;
    }

    /**
     * @dev Keep things sorted as we go.
     *      Only works for no downvoting bc dealing w what happens when something leaves the top ranks and needs to be *replaced* is an issue that necessitates the sorting of all the others, which we don't want to do bc gas.
     *      Invariant: Because of no downvoting, and that a vote of 0 is not allowed, newValue will always be greater than oldValue.
     */
    function _updateRanks(uint256 oldValue, uint256 newValue) internal {
        uint256 sortedRanksLength = sortedRanks.length; // only check state var once to save on gas
        uint256[] memory sortedRanksMemVar = sortedRanks; // only check state var once to save on gas

        // FIRST ENTRY? - if this is the first item ever then we just need to put it in idx 0 and that's it
        if (sortedRanksLength == 0) {
            sortedRanks.push(newValue);
            return;
        }

        // SMALLER THAN CURRENT SMALLEST VAL?
        // this also means that the old value was 0 (or less than the lowest value if sortedRanks.length == RANK_LIMIT and/or the array is full), so all good with regards to oldValue.
        if (newValue < sortedRanksMemVar[sortedRanksLength - 1]) {
            if (sortedRanksLength == rankLimit) {
                // if we've reached the size limit of sortedRanks, then we're done here
                return;
            } else {
                // otherwise, put this value in the index after the current smallest value
                sortedRanks.push(newValue);
                return;
            }
        }

        // SO IT'S IN [0, sortedRanksLength - 1]!
        // find where it should go and insert it.
        _insertRank(oldValue, newValue, sortedRanksLength, sortedRanksMemVar);
    }
}

/**
 * @dev Core of the governance system, designed to be extended though various modules.
 */
abstract contract Governor is GovernorSorting, GovernorMerkleVotes {
    using SafeCast for uint256;

    enum ContestState {
        NotStarted,
        Active,
        Canceled,
        Queued,
        Completed
    }

    enum Metadatas {
        Target,
        Safe
    }

    enum Actions {
        Submit,
        Vote
    }

    struct ConstructorIntArgs {
        uint256 contestStart;
        uint256 votingDelay;
        uint256 votingPeriod;
        uint256 numAllowedProposalSubmissions;
        uint256 maxProposalCount;
        uint256 downvotingAllowed;
        uint256 sortingEnabled;
        uint256 rankLimit;
        uint256 percentageToCreator;
        uint256 costToPropose;
        uint256 costToVote;
    }

    struct TargetMetadata {
        address targetAddress;
    }

    struct SafeMetadata {
        address[] signers;
        uint256 threshold;
    }

    struct ProposalCore {
        address author;
        bool exists;
        string description;
        TargetMetadata targetMetadata;
        SafeMetadata safeMetadata;
    }

    event JokeraceCreated(
        string version,
        string name,
        string prompt,
        address creator,
        uint256 contestStart,
        uint256 votingDelay,
        uint256 votingPeriod
    );
    event ProposalCreated(uint256 proposalId, address proposer, string proposalDescription);
    event ProposalsDeleted(uint256[] proposalIds);
    event ContestCanceled();
    event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 numVotes);
    event PaymentReleased(address to, uint256 amount);

    uint256 public constant METADATAS_COUNT = uint256(type(Metadatas).max) + 1;
    uint256 public constant AMOUNT_FOR_SUMBITTER_PROOF = 10000000000000000000;
    address public constant JK_LABS_ADDRESS = 0xDc652C746A8F85e18Ce632d97c6118e8a52fa738;
    string private constant VERSION = "4.24"; // Private as to not clutter the ABI

    string public name; // The title of the contest
    string public prompt;
    address public creator;
    uint256 public contestStart; // The Unix timestamp that the contest starts at.
    uint256 public votingDelay; // Number of seconds that submissions are open.
    uint256 public votingPeriod; // Number of seconds that voting is open.
    uint256 public numAllowedProposalSubmissions; // The number of proposals that an address who is qualified to propose can submit for this contest.
    uint256 public maxProposalCount; // Max number of proposals allowed in this contest.
    uint256 public downvotingAllowed; // If downvoting is enabled in this contest.
    uint256 public percentageToCreator;
    uint256 public costToPropose;
    uint256 public costToVote;

    uint256[] public proposalIds;
    uint256[] public deletedProposalIds;
    mapping(uint256 => bool) public proposalIsDeleted;
    bool public canceled;
    mapping(uint256 => ProposalCore) public proposals;
    mapping(address => uint256) public numSubmissions;
    address[] public proposalAuthors;
    address[] public addressesThatHaveVoted;

    mapping(address => uint256) public addressTotalVotes;
    mapping(address => bool) public addressTotalVotesVerified;
    mapping(address => bool) public addressSubmitterVerified;

    error AuthorIsNotSender(address author, address sender);
    error ZeroSignersInSafeMetadata();
    error ZeroThresholdInSafeMetadata();
    error UnexpectedMetadata(Metadatas unexpectedMetadata);
    error EmptyProposalDescription();

    error IncorrectCostSent(uint256 msgValue, uint256 costToVote);

    error AddressNotPermissionedToSubmit();
    error ContestMustBeQueuedToPropose(ContestState currentState);
    error ContestMustBeActiveToVote(ContestState currentState);
    error SenderSubmissionLimitReached(uint256 numAllowedProposalSubmissions);
    error ContestSubmissionLimitReached(uint256 maxProposalCount);
    error DuplicateSubmission(uint256 proposalId);

    error CannotVoteOnDeletedProposal();
    error NeedAtLeastOneVoteToVote();

    error NeedToSubmitWithProofFirst();
    error NeedToVoteWithProofFirst();

    error OnlyCreatorCanDelete();
    error CannotDeleteWhenCompleted();

    error OnlyJkLabsOrCreatorCanCancel();
    error ContestAlreadyCancelled();

    error OnlyJkLabsCanAmend();

    constructor(
        string memory name_,
        string memory prompt_,
        bytes32 submissionMerkleRoot_,
        bytes32 votingMerkleRoot_,
        ConstructorIntArgs memory constructorIntArgs_
    ) GovernorMerkleVotes(submissionMerkleRoot_, votingMerkleRoot_) {
        name = name_;
        prompt = prompt_;
        creator = msg.sender;
        contestStart = constructorIntArgs_.contestStart;
        votingDelay = constructorIntArgs_.votingDelay;
        votingPeriod = constructorIntArgs_.votingPeriod;
        numAllowedProposalSubmissions = constructorIntArgs_.numAllowedProposalSubmissions;
        maxProposalCount = constructorIntArgs_.maxProposalCount;
        downvotingAllowed = constructorIntArgs_.downvotingAllowed;
        percentageToCreator = constructorIntArgs_.percentageToCreator;
        costToPropose = constructorIntArgs_.costToPropose;
        costToVote = constructorIntArgs_.costToVote;

        emit JokeraceCreated(
            VERSION,
            name_,
            prompt_,
            msg.sender,
            constructorIntArgs_.contestStart,
            constructorIntArgs_.votingDelay,
            constructorIntArgs_.votingPeriod
        ); // emit upon creation to be able to easily find jokeraces on a chain
    }

    function version() public pure returns (string memory) {
        return VERSION;
    }

    function hashProposal(ProposalCore memory proposal) public pure returns (uint256) {
        return uint256(keccak256(abi.encode(proposal)));
    }

    function state() public view returns (ContestState) {
        if (canceled) {
            return ContestState.Canceled;
        }

        if (contestStart >= block.timestamp) {
            return ContestState.NotStarted;
        }

        if (voteStart() >= block.timestamp) {
            return ContestState.Queued;
        }

        if (contestDeadline() >= block.timestamp) {
            return ContestState.Active;
        }

        return ContestState.Completed;
    }

    /**
     * @dev Return all proposals.
     */
    function getAllProposalIds() public view returns (uint256[] memory) {
        return proposalIds;
    }

    /**
     * @dev Return all proposal authors.
     */
    function getAllProposalAuthors() public view returns (address[] memory) {
        return proposalAuthors;
    }

    /**
     * @dev Return all addresses that have voted.
     */
    function getAllAddressesThatHaveVoted() public view returns (address[] memory) {
        return addressesThatHaveVoted;
    }

    /**
     * @dev Return all deleted proposals.
     */
    function getAllDeletedProposalIds() public view returns (uint256[] memory) {
        return deletedProposalIds;
    }

    /**
     * @dev Return all authors of deleted proposals.
     */
    function getAllAuthorsOfDeletedProposals() public view returns (address[] memory) {
        uint256[] memory deletedProposalIdsMemVar = deletedProposalIds;
        address[] memory authorsArray = new address[](deletedProposalIdsMemVar.length);
        for (uint256 i = 0; i < deletedProposalIdsMemVar.length; i++) {
            authorsArray[i] = proposals[deletedProposalIdsMemVar[i]].author;
        }
        return authorsArray;
    }

    /**
     * @dev Timestamp the contest vote begins. Votes open at the end of this block, so it is possible to propose
     * during this block.
     */
    function voteStart() public view returns (uint256) {
        return contestStart + votingDelay;
    }

    /**
     * @dev Returns if a proposal has been deleted or not.
     */
    function contestDeadline() public view returns (uint256) {
        return voteStart() + votingPeriod;
    }

    /**
     * @dev Retrieve proposal data.
     */
    function getProposal(uint256 proposalId) public view returns (ProposalCore memory) {
        return proposals[proposalId];
    }

    /**
     * @dev Remove deleted proposalIds from forVotesToProposalIds and decrement copy counts of the forVotes of proposalIds.
     */
    function _multiRmProposalIdFromForVotesMap(uint256[] calldata proposalIds) internal virtual;

    /**
     * @dev Register a vote with a given support and voting weight.
     *
     * Note: Support is generic and can represent various things depending on the voting system used.
     */
    function _countVote(uint256 proposalId, address account, uint8 support, uint256 numVotes, uint256 totalVotes)
        internal
        virtual;

    /**
     * @dev Verifies that `account` is permissioned to propose via merkle proof.
     */
    function verifyProposer(address account, bytes32[] calldata proof) public {
        if (!addressSubmitterVerified[account]) {
            if (submissionMerkleRoot == 0) {
                // if the submission root is 0, then anyone can submit
                return;
            }
            checkProof(account, AMOUNT_FOR_SUMBITTER_PROOF, proof, false); // will revert with NotInMerkle if not valid
            addressSubmitterVerified[account] = true;
        }
    }

    /**
     * @dev Verifies that all of the metadata in the proposal is valid.
     */
    function validateProposalData(ProposalCore memory proposal) public view {
        if (proposal.author != msg.sender) revert AuthorIsNotSender(proposal.author, msg.sender);
        for (uint256 index = 0; index < METADATAS_COUNT; index++) {
            Metadatas currentMetadata = Metadatas(index);
            if (currentMetadata == Metadatas.Target) {
                continue; // Nothing to check here since strictly typed to address
            } else if (currentMetadata == Metadatas.Safe) {
                if (proposal.safeMetadata.signers.length == 0) revert ZeroSignersInSafeMetadata();
                if (proposal.safeMetadata.threshold == 0) revert ZeroThresholdInSafeMetadata();
            } else {
                revert UnexpectedMetadata(currentMetadata);
            }
        }
        if (bytes(proposal.description).length == 0) revert EmptyProposalDescription();
    }

    /**
     * @dev Determines that the correct amount was sent with the transaction and returns that correct amount.
     */
    function _determineCorrectAmountSent(Actions currentAction) internal returns (uint256) {
        uint256 actionCost;
        if (currentAction == Actions.Submit) {
            actionCost = costToPropose;
        } else if (currentAction == Actions.Vote) {
            actionCost = costToVote;
        } else {
            actionCost = 0;
        }

        if (msg.value != actionCost) revert IncorrectCostSent(msg.value, actionCost);
        return actionCost;
    }

    /**
     * @dev Distribute the costToPropose to jk labs and the creator based on _percentageToCreator.
     */
    function _distributeCost(uint256 actionCost) internal {
        if (actionCost > 0) {
            // Send proposal fee to jk labs address and creator
            uint256 sendingToJkLabs = (msg.value * (100 - percentageToCreator)) / 100;
            if (sendingToJkLabs > 0) {
                Address.sendValue(payable(JK_LABS_ADDRESS), sendingToJkLabs);
                emit PaymentReleased(JK_LABS_ADDRESS, sendingToJkLabs);
            }

            uint256 sendingToCreator = msg.value - sendingToJkLabs;
            if (sendingToCreator > 0) {
                Address.sendValue(payable(creator), sendingToCreator); // creator gets the extra wei in the case of rounding
                emit PaymentReleased(creator, sendingToCreator);
            }
        }
    }

    /**
     * @dev Create a new proposal.
     */
    function propose(ProposalCore calldata proposal, bytes32[] calldata proof) public payable returns (uint256) {
        uint256 actionCost = _determineCorrectAmountSent(Actions.Submit);

        verifyProposer(msg.sender, proof);
        validateProposalData(proposal);
        uint256 proposalId = _castProposal(proposal);

        _distributeCost(actionCost);

        return proposalId;
    }

    /**
     * @dev Create a new proposal without a proof if you have already proposed with a proof.
     */
    function proposeWithoutProof(ProposalCore calldata proposal) public payable returns (uint256) {
        uint256 actionCost = _determineCorrectAmountSent(Actions.Submit);

        if (submissionMerkleRoot != 0) {
            // if the submission root is 0, then anyone can submit; otherwise, this address needs to have been verified
            if (!addressSubmitterVerified[msg.sender]) revert NeedToSubmitWithProofFirst();
        }
        validateProposalData(proposal);
        uint256 proposalId = _castProposal(proposal);

        _distributeCost(actionCost);

        return proposalId;
    }

    function _castProposal(ProposalCore memory proposal) internal returns (uint256) {
        if (state() != ContestState.Queued) revert ContestMustBeQueuedToPropose(state());
        if (numSubmissions[msg.sender] == numAllowedProposalSubmissions) {
            revert SenderSubmissionLimitReached(numAllowedProposalSubmissions);
        }
        if ((proposalIds.length - deletedProposalIds.length) == maxProposalCount) {
            revert ContestSubmissionLimitReached(maxProposalCount);
        }

        uint256 proposalId = hashProposal(proposal);
        if (proposals[proposalId].exists) revert DuplicateSubmission(proposalId);

        proposalIds.push(proposalId);
        proposals[proposalId] = proposal;
        numSubmissions[msg.sender] += 1;
        proposalAuthors.push(msg.sender);

        emit ProposalCreated(proposalId, msg.sender, proposal.description);

        return proposalId;
    }

    /**
     * @dev Delete proposals.
     *
     * Emits a {IGovernor-ProposalsDeleted} event.
     */
    function deleteProposals(uint256[] calldata proposalIdsToDelete) public {
        if (msg.sender != creator) revert OnlyCreatorCanDelete();
        if (state() == ContestState.Completed) revert CannotDeleteWhenCompleted();

        for (uint256 index = 0; index < proposalIdsToDelete.length; index++) {
            uint256 currentProposalId = proposalIdsToDelete[index];
            if (!proposalIsDeleted[currentProposalId]) {
                // if this proposal hasn't already been deleted
                proposalIsDeleted[currentProposalId] = true;
                // this proposal now won't count towards the total number allowed in the contest
                // it will still count towards the total number of proposals that the user is allowed to submit though
                deletedProposalIds.push(currentProposalId);
            }
        }

        // we only do sorting if downvoting is disabled and if sorting is enabled
        if (downvotingAllowed == 0 && sortingEnabled == 1) {
            // remove proposalIds from forVotesToProposalIds (could contain proposalIds that have been deleted before, that's ok though)
            _multiRmProposalIdFromForVotesMap(proposalIdsToDelete);
        }

        emit ProposalsDeleted(proposalIds);
    }

    /**
     * @dev Cancels the contest.
     *
     * Emits a {IGovernor-ContestCanceled} event.
     */
    function cancel() public {
        if (((msg.sender != creator) && (msg.sender != JK_LABS_ADDRESS))) revert OnlyJkLabsOrCreatorCanCancel();

        ContestState status = state();
        if (status == ContestState.Canceled) revert ContestAlreadyCancelled();

        canceled = true;

        emit ContestCanceled();
    }

    /**
     * @dev Verifies that `account` is permissioned to vote with `totalVotes` via merkle proof.
     */
    function verifyVoter(address account, uint256 totalVotes, bytes32[] calldata proof) public {
        if (!addressTotalVotesVerified[account]) {
            checkProof(account, totalVotes, proof, true); // will revert with NotInMerkle if not valid
            addressTotalVotes[account] = totalVotes;
            addressTotalVotesVerified[account] = true;
        }
    }

    /**
     * @dev Cast a vote with a merkle proof.
     */
    function castVote(uint256 proposalId, uint8 support, uint256 totalVotes, uint256 numVotes, bytes32[] calldata proof)
        public
        payable
        returns (uint256)
    {
        uint256 actionCost = _determineCorrectAmountSent(Actions.Vote);

        address voter = msg.sender;
        if (proposalIsDeleted[proposalId]) revert CannotVoteOnDeletedProposal();
        verifyVoter(voter, totalVotes, proof);

        _distributeCost(actionCost);

        return _castVote(proposalId, voter, support, numVotes);
    }

    /**
     * @dev Cast a vote without a proof if you have already voted with a proof.
     */
    function castVoteWithoutProof(uint256 proposalId, uint8 support, uint256 numVotes)
        public
        payable
        returns (uint256)
    {
        uint256 actionCost = _determineCorrectAmountSent(Actions.Vote);

        address voter = msg.sender;
        if (proposalIsDeleted[proposalId]) revert CannotVoteOnDeletedProposal();
        if (!addressTotalVotesVerified[voter]) revert NeedToVoteWithProofFirst();

        _distributeCost(actionCost);

        return _castVote(proposalId, voter, support, numVotes);
    }

    /**
     * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve
     * voting weight using addressTotalVotes() and call the {_countVote} internal function.
     *
     * Emits a {IGovernor-VoteCast} event.
     */
    function _castVote(uint256 proposalId, address account, uint8 support, uint256 numVotes)
        internal
        returns (uint256)
    {
        if (state() != ContestState.Active) revert ContestMustBeActiveToVote(state());
        if (numVotes == 0) revert NeedAtLeastOneVoteToVote();

        _countVote(proposalId, account, support, numVotes, addressTotalVotes[account]);

        addressesThatHaveVoted.push(msg.sender);

        emit VoteCast(account, proposalId, support, numVotes);

        return addressTotalVotes[account];
    }

    function setSubmissionMerkleRoot(bytes32 newSubmissionMerkleRoot) public {
        if (msg.sender != JK_LABS_ADDRESS) revert OnlyJkLabsCanAmend();
        submissionMerkleRoot = newSubmissionMerkleRoot;
    }

    function setVotingMerkleRoot(bytes32 newVotingMerkleRoot) public {
        if (msg.sender != JK_LABS_ADDRESS) revert OnlyJkLabsCanAmend();
        votingMerkleRoot = newVotingMerkleRoot;
    }
}

// Forked from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/governance/extensions/GovernorCountingSimple.sol

/**
 * @dev Extension of {Governor} for simple vote counting.
 */
abstract contract GovernorCountingSimple is Governor {
    /**
     * @dev Supported vote types. Matches Governor Bravo ordering.
     */
    enum VoteType {
        For,
        Against
    }

    struct VoteCounts {
        uint256 forVotes;
        uint256 againstVotes;
    }

    struct ProposalVote {
        VoteCounts proposalVoteCounts;
        address[] addressesVoted;
        mapping(address => VoteCounts) addressVoteCounts;
    }

    uint256 public totalVotesCast; // Total votes cast in contest so far
    mapping(address => uint256) public addressTotalCastVoteCounts;
    mapping(uint256 => ProposalVote) public proposalVotesStructs;

    mapping(uint256 => uint256[]) public forVotesToProposalIds;

    error MoreThanOneProposalWithThisManyVotes();
    error NotEnoughVotesLeft();
    error DownvotingNotEnabled();
    error InvalidVoteType();

    error RankCannotBeZero();
    error RankIsNotInSortedRanks();
    error IndexHasNotBeenPopulated();

    /**
     * @dev Accessor to the internal vote counts for a given proposal.
     */
    function proposalVotes(uint256 proposalId) public view returns (uint256 forVotes, uint256 againstVotes) {
        ProposalVote storage proposalvote = proposalVotesStructs[proposalId];
        return (proposalvote.proposalVoteCounts.forVotes, proposalvote.proposalVoteCounts.againstVotes);
    }

    /**
     * @dev Accessor to how many votes an address has cast for a given proposal.
     */
    function proposalAddressVotes(uint256 proposalId, address userAddress)
        public
        view
        returns (uint256 forVotes, uint256 againstVotes)
    {
        ProposalVote storage proposalvote = proposalVotesStructs[proposalId];
        return (
            proposalvote.addressVoteCounts[userAddress].forVotes,
            proposalvote.addressVoteCounts[userAddress].againstVotes
        );
    }

    /**
     * @dev Accessor to which addresses have cast a vote for a given proposal.
     */
    function proposalAddressesHaveVoted(uint256 proposalId) public view returns (address[] memory) {
        ProposalVote storage proposalvote = proposalVotesStructs[proposalId];
        return proposalvote.addressesVoted;
    }

    /**
     * @dev Accessor to how many votes an address has cast total for the contest so far.
     */
    function contestAddressTotalVotesCast(address userAddress) public view returns (uint256 userTotalVotesCast) {
        return addressTotalCastVoteCounts[userAddress];
    }

    /**
     * @dev Accessor to the internal vote counts for a given proposal.
     */
    function allProposalTotalVotes()
        public
        view
        returns (uint256[] memory proposalIdsReturn, VoteCounts[] memory proposalVoteCountsArrayReturn)
    {
        uint256[] memory proposalIdsMemVar = getAllProposalIds();
        VoteCounts[] memory proposalVoteCountsArray = new VoteCounts[](proposalIdsMemVar.length);
        for (uint256 i = 0; i < proposalIdsMemVar.length; i++) {
            proposalVoteCountsArray[i] = proposalVotesStructs[proposalIdsMemVar[i]].proposalVoteCounts;
        }
        return (proposalIdsMemVar, proposalVoteCountsArray);
    }

    /**
     * @dev Get the whole array in `forVotesToProposalIds` for a given `forVotes` amount.
     */
    function getProposalsWithThisManyForVotes(uint256 forVotes)
        public
        view
        returns (uint256[] memory proposalsWithThisManyForVotes)
    {
        return forVotesToProposalIds[forVotes];
    }

    /**
     * @dev Get the number of proposals that have `forVotes` number of for votes.
     */
    function getNumProposalsWithThisManyForVotes(uint256 forVotes) public view override returns (uint256 count) {
        return forVotesToProposalIds[forVotes].length;
    }

    /**
     * @dev Get the only proposal id with this many for votes.
     * NOTE: Should only get called at a point at which you are sure there is only one proposal id
     *       with a certain number of forVotes (we only use it in the RewardsModule after ties have
     *       been checked for).
     */
    function getOnlyProposalIdWithThisManyForVotes(uint256 forVotes) public view returns (uint256 proposalId) {
        if (forVotesToProposalIds[forVotes].length != 1) revert MoreThanOneProposalWithThisManyVotes();
        return forVotesToProposalIds[forVotes][0];
    }

    /**
     * @dev Get the idx of sortedRanks considered to hold the queried rank taking deleted proposals into account.
     *      A rank has to have > 0 votes to be considered valid.
     */
    function getRankIndex(uint256 rank) public view returns (uint256 rankIndex) {
        if (rank == 0) revert RankCannotBeZero();

        uint256 sortedRanksLength = sortedRanks.length; // only check state var once to save on gas
        uint256[] memory sortedRanksMemVar = sortedRanks; // only check state var once to save on gas

        uint256 counter = 1;
        for (uint256 index = 0; index < sortedRanksLength; index++) {
            // if this is a value of a deleted proposal or an ungarbage collected oldValue, go forwards without
            // incrementing the counter
            if (getNumProposalsWithThisManyForVotes(sortedRanksMemVar[index]) == 0) {
                continue;
            }
            // if the counter is at the rank we are looking for, then return with it
            if (counter == rank) {
                return index;
            }
            counter++;
        }

        // if there's no valid index for that rank in sortedRanks, revert
        revert RankIsNotInSortedRanks();
    }

    /**
     * @dev Returns whether a given index in sortedRanks is tied or is below a tied rank.
     */
    function isOrIsBelowTiedRank(uint256 idx) public view returns (bool atOrBelowTiedRank) {
        if (idx > sortedRanks.length - 1) {
            // if `idx` hasn't been populated, then it's not a valid index to be checking and something is wrong
            revert IndexHasNotBeenPopulated();
        }

        for (uint256 index = 0; index < idx + 1; index++) {
            if (getNumProposalsWithThisManyForVotes(sortedRanks[index]) > 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * @dev Remove this proposalId from the list of proposalIds that share its current forVotes
     *      value in forVotesToProposalIds.
     */
    function _rmProposalIdFromForVotesMap(uint256 proposalId, uint256 forVotes) internal {
        uint256[] memory forVotesToPropIdMemVar = forVotesToProposalIds[forVotes]; // only check state var once to save on gas
        for (uint256 i = 0; i < forVotesToPropIdMemVar.length; i++) {
            if (forVotesToPropIdMemVar[i] == proposalId) {
                // swap with last item and pop bc we don't care about order.
                // makes things cleaner (than just deleting) and saves on gas if there end up being a ton of proposals that pass
                // through having a certain number of votes throughout the contest.
                forVotesToProposalIds[forVotes][i] = forVotesToPropIdMemVar[forVotesToPropIdMemVar.length - 1];
                forVotesToProposalIds[forVotes].pop();
                break;
            }
        }
    }

    /**
     * @dev See {Governor-_multiRmProposalIdFromForVotesMap}.
     */
    function _multiRmProposalIdFromForVotesMap(uint256[] calldata proposalIdsToDelete) internal override {
        for (uint256 i = 0; i < proposalIdsToDelete.length; i++) {
            uint256 currentProposalId = proposalIdsToDelete[i];
            uint256 currentProposalsForVotes = proposalVotesStructs[currentProposalId].proposalVoteCounts.forVotes;

            // remove this proposalId from the list of proposalIdsToDelete that share its current forVotes
            // value in forVotesToProposalIds
            _rmProposalIdFromForVotesMap(currentProposalId, currentProposalsForVotes);
        }
    }

    /**
     * @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo).
     */
    function _countVote(uint256 proposalId, address account, uint8 support, uint256 numVotes, uint256 totalVotes)
        internal
        override
    {
        ProposalVote storage proposalvote = proposalVotesStructs[proposalId];

        if (numVotes > (totalVotes - addressTotalCastVoteCounts[account])) revert NotEnoughVotesLeft();

        bool firstTimeVoting = (
            proposalvote.addressVoteCounts[account].forVotes == 0
                && proposalvote.addressVoteCounts[account].againstVotes == 0
        );

        if (support == uint8(VoteType.For)) {
            proposalvote.proposalVoteCounts.forVotes += numVotes;
            proposalvote.addressVoteCounts[account].forVotes += numVotes;
        } else if (support == uint8(VoteType.Against)) {
            if (downvotingAllowed != 1) revert DownvotingNotEnabled();
            proposalvote.proposalVoteCounts.againstVotes += numVotes;
            proposalvote.addressVoteCounts[account].againstVotes += numVotes;
        } else {
            revert InvalidVoteType();
        }

        if (firstTimeVoting) {
            proposalvote.addressesVoted.push(account);
        }
        addressTotalCastVoteCounts[account] += numVotes;
        totalVotesCast += numVotes;

        // sorting and consequently rewards module compatibility is only available if downvoting is disabled and sorting enabled
        if ((downvotingAllowed == 0) && (sortingEnabled == 1)) {
            uint256 newForVotes = proposalvote.proposalVoteCounts.forVotes; // only check state var once to save on gas
            uint256 oldForVotes = newForVotes - numVotes;

            // update map of forVotes => proposalId[] to be able to go from rank => proposalId.
            // if oldForVotes is 0, then this proposal will not already be in this map, so we don't need to rm it
            if (oldForVotes > 0) {
                _rmProposalIdFromForVotesMap(proposalId, oldForVotes);
            }
            forVotesToProposalIds[newForVotes].push(proposalId);

            _updateRanks(oldForVotes, newForVotes);
        }
    }
}

// Forked from OpenZeppelin Contracts (v4.7.0) (finance/PaymentSplitter.sol)

// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)

// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to
     * 0 before setting it to a non-zero value.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}

/**
 * @title RewardsModule
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned. The distribution of shares is set at the
 * time of contract deployment and can't be updated thereafter.
 *
 * `RewardsModule` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 *
 * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
 * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
 * to run tests before sending real value to this contract.
 */
contract RewardsModule {
    event PayeeAdded(uint256 ranking, uint256 shares);
    event PaymentReleased(address to, uint256 amount);
    event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
    event PaymentReceived(address from, uint256 amount);
    event RewardWithdrawn(address by, uint256 amount);
    event ERC20RewardWithdrawn(IERC20 indexed token, address by, uint256 amount);

    uint256 public totalShares;
    uint256 public totalReleased;

    mapping(uint256 => uint256) public shares; // Getter for the amount of shares held by a ranking.
    mapping(uint256 => uint256) public released; // Getter for the amount of Ether already released to a ranking.
    uint256[] public payees;
    string private constant VERSION = "4.24"; // Private as to not clutter the ABI

    mapping(IERC20 => uint256) public erc20TotalReleased;
    mapping(IERC20 => mapping(uint256 => uint256)) public erc20Released;

    GovernorCountingSimple public underlyingContest;
    address public creator;
    bool public paysOutTarget; // If true, pay out target address; if false, pay out proposal author.

    error PayeesSharesLengthMismatch();
    error MustHaveAtLeastOnePayee();
    error TotalSharesCannotBeZero();
    error MustHaveDownvotingDisabled();
    error MustHaveSortingEnabled();
    error ContestMustBeCompleted();
    error PayoutRankCannotBeZero();
    error RankingHasNoShares();
    error AccountNotDueNativePayment();
    error CannotPayOutToZeroAddress();
    error AccountNotDueERC20Payment();
    error OnlyCreatorCanWithdraw();
    error RankingCannotBeZero();
    error SharesCannotBeZero();
    error AccountAlreadyHasShares();

    /**
     * @dev Creates an instance of `RewardsModule` where each ranking in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All rankings in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(
        uint256[] memory payees_,
        uint256[] memory shares_,
        GovernorCountingSimple underlyingContest_,
        bool paysOutTarget_
    ) payable {
        if (payees_.length != shares_.length) revert PayeesSharesLengthMismatch();
        if (payees_.length == 0) revert MustHaveAtLeastOnePayee();

        for (uint256 i = 0; i < payees_.length; i++) {
            _addPayee(payees_[i], shares_[i]);
        }

        if (totalShares == 0) revert TotalSharesCannotBeZero();

        paysOutTarget = paysOutTarget_;
        underlyingContest = underlyingContest_;
        creator = msg.sender;
    }

    /**
     * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
     * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
     * reliability of the events, and not the actual splitting of Ether.
     */
    receive() external payable {
        emit PaymentReceived(msg.sender, msg.value);
    }

    /**
     * @dev Version of the rewards module.
     */
    function version() public pure returns (string memory) {
        return VERSION;
    }

    /**
     * @dev Getter for list of rankings that will be paid out.
     */
    function getPayees() public view returns (uint256[] memory) {
        return payees;
    }

    /**
     * @dev Getter for the underlying contest.
     */
    function getUnderlyingContest() public view returns (GovernorCountingSimple) {
        return underlyingContest;
    }

    /**
     * @dev Getter for the amount of payee's releasable Ether.
     */
    function releasable(uint256 ranking) public view returns (uint256) {
        uint256 totalReceived = address(this).balance + totalReleased;
        return _pendingPayment(ranking, totalReceived, released[ranking]);
    }

    /**
     * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an
     * IERC20 contract.
     */
    function releasable(IERC20 token, uint256 ranking) public view returns (uint256) {
        uint256 totalReceived = token.balanceOf(address(this)) + erc20TotalReleased[token];
        return _pendingPayment(ranking, totalReceived, erc20Released[token][ranking]);
    }

    /**
     * @dev Run release checks.
     */
    function runReleaseChecks(uint256 ranking) public view {
        if (underlyingContest.downvotingAllowed() != 0) revert MustHaveDownvotingDisabled();
        if (underlyingContest.sortingEnabled() != 1) revert MustHaveSortingEnabled();
        if (underlyingContest.state() != Governor.ContestState.Completed) revert ContestMustBeCompleted();
        if (ranking == 0) revert PayoutRankCannotBeZero();
        if (shares[ranking] == 0) revert RankingHasNoShares();
    }

    /**
     * @dev Return address to pay out for a given ranking.
     */
    function getAddressToPayOut(uint256 ranking) public view returns (address) {
        address addressToPayOut;
        uint256 determinedRankingIdxInSortedRanks = underlyingContest.getRankIndex(ranking);

        // if the ranking that we land on is tied or it's below a tied ranking, send to creator
        if (underlyingContest.isOrIsBelowTiedRank(determinedRankingIdxInSortedRanks)) {
            addressToPayOut = creator;
        }
        // otherwise, determine proposal at ranking and pay out according to that
        else {
            uint256 rankValue = underlyingContest.sortedRanks(determinedRankingIdxInSortedRanks);
            Governor.ProposalCore memory rankingProposal = underlyingContest.getProposal(
                underlyingContest.getOnlyProposalIdWithThisManyForVotes(rankValue) // if no ties there should only be one
            );
            addressToPayOut = paysOutTarget ? rankingProposal.targetMetadata.targetAddress : rankingProposal.author;
        }

        return addressToPayOut;
    }

    /**
     * @dev Triggers a transfer to `ranking` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function release(uint256 ranking) public {
        runReleaseChecks(ranking);

        uint256 payment = releasable(ranking);

        if (payment == 0) revert AccountNotDueNativePayment();

        // totalReleased is the sum of all values in released.
        // If "totalReleased += payment" does not overflow, then "released[account] += payment" cannot overflow.
        totalReleased += payment;
        unchecked {
            released[ranking] += payment;
        }

        address payable addressToPayOut = payable(getAddressToPayOut(ranking));

        if (addressToPayOut == address(0)) revert CannotPayOutToZeroAddress();

        emit PaymentReleased(addressToPayOut, payment);
        Address.sendValue(addressToPayOut, payment);
    }

    /**
     * @dev Triggers a transfer to `ranking` of the amount of `token` tokens they are owed, according to their
     * percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
     * contract.
     */
    function release(IERC20 token, uint256 ranking) public {
        runReleaseChecks(ranking);

        uint256 payment = releasable(token, ranking);

        if (payment == 0) revert AccountNotDueERC20Payment();

        // erc20TotalReleased[token] is the sum of all values in erc20Released[token].
        // If "erc20TotalReleased[token] += payment" does not overflow, then "erc20Released[token][account] += payment" cannot overflow.
        erc20TotalReleased[token] += payment;
        unchecked {
            erc20Released[token][ranking] += payment;
        }

        address payable addressToPayOut = payable(getAddressToPayOut(ranking));

        if (addressToPayOut == address(0)) revert CannotPayOutToZeroAddress();

        emit ERC20PaymentReleased(token, addressToPayOut, payment);
        SafeERC20.safeTransfer(token, addressToPayOut, payment);
    }

    function withdrawRewards() public {
        if (msg.sender != creator) revert OnlyCreatorCanWithdraw();

        emit RewardWithdrawn(creator, address(this).balance);
        Address.sendValue(payable(creator), address(this).balance);
    }

    function withdrawRewards(IERC20 token) public {
        if (msg.sender != creator) revert OnlyCreatorCanWithdraw();

        emit ERC20RewardWithdrawn(token, creator, token.balanceOf(address(this)));
        SafeERC20.safeTransfer(token, payable(creator), token.balanceOf(address(this)));
    }

    /**
     * @dev internal logic for computing the pending payment of a `ranking` given the token historical balances and
     * already released amounts.
     */
    function _pendingPayment(uint256 ranking, uint256 totalReceived, uint256 alreadyReleased)
        private
        view
        returns (uint256)
    {
        return (totalReceived * shares[ranking]) / totalShares - alreadyReleased;
    }

    /**
     * @dev Add a new payee to the contract.
     * @param ranking The ranking of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(uint256 ranking, uint256 shares_) private {
        if (ranking == 0) revert RankingCannotBeZero();
        if (shares_ == 0) revert SharesCannotBeZero();
        if (shares[ranking] != 0) revert AccountAlreadyHasShares();

        payees.push(ranking);
        shares[ranking] = shares_;
        totalShares = totalShares + shares_;
        emit PayeeAdded(ranking, shares_);
    }
}

/**
 * @dev Extension of {Governor} for module management.
 */
abstract contract GovernorModuleRegistry is Governor {
    event OfficialRewardsModuleSet(RewardsModule oldOfficialRewardsModule, RewardsModule newOfficialRewardsModule);

    RewardsModule public officialRewardsModule;

    error OnlyCreatorCanSetRewardsModule();

    /**
     * @dev Get the official rewards module contract for this contest (effectively reverse record).
     */
    function setOfficialRewardsModule(RewardsModule officialRewardsModule_) public {
        if (msg.sender != creator) revert OnlyCreatorCanSetRewardsModule();
        RewardsModule oldOfficialRewardsModule = officialRewardsModule;
        officialRewardsModule = officialRewardsModule_;
        emit OfficialRewardsModuleSet(oldOfficialRewardsModule, officialRewardsModule_);
    }
}

/**
 * @dev Extension of {Governor} for engagement features.
 */
abstract contract GovernorEngagement is Governor {
    struct CommentCore {
        address author;
        uint256 timestamp;
        uint256 proposalId;
        string commentContent;
    }

    /**
     * @dev Emitted when a comment is created.
     */
    event CommentCreated(uint256 commentId);

    /**
     * @dev Emitted when comments are deleted.
     */
    event CommentsDeleted(uint256[] commentIds);

    uint256[] public commentIds;
    uint256[] public deletedCommentIds;
    mapping(uint256 => CommentCore) public comments;
    mapping(uint256 => uint256[]) public proposalComments;
    mapping(uint256 => bool) public commentIsDeleted;

    error OnlyCreatorOrAuthorCanDeleteComments(uint256 failedToDeleteCommentId);

    /**
     * @dev Hashing function used to build the comment id from the comment details.
     */
    function hashComment(CommentCore memory commentObj) public pure returns (uint256) {
        return uint256(keccak256(abi.encode(commentObj)));
    }

    /**
     * @dev Return all commentIds.
     */
    function getAllCommentIds() public view returns (uint256[] memory) {
        return commentIds;
    }

    /**
     * @dev Return all deleted commentIds.
     */
    function getAllDeletedCommentIds() public view returns (uint256[] memory) {
        return deletedCommentIds;
    }

    /**
     * @dev Return a comment object.
     */
    function getComment(uint256 commentId) public view returns (CommentCore memory) {
        return comments[commentId];
    }

    /**
     * @dev Return the array of commentIds on a given proposalId.
     */
    function getProposalComments(uint256 proposalId) public view returns (uint256[] memory) {
        return proposalComments[proposalId];
    }

    /**
     * @dev Comment on a proposal.
     *
     * Emits a {CommentCreated} event.
     */
    function comment(uint256 proposalId, string memory commentContent) public returns (uint256) {
        CommentCore memory commentObject = CommentCore({
            author: msg.sender,
            timestamp: block.timestamp,
            proposalId: proposalId,
            commentContent: commentContent
        });
        uint256 commentId = hashComment(commentObject);

        commentIds.push(commentId);
        comments[commentId] = commentObject;
        proposalComments[proposalId].push(commentId);

        emit CommentCreated(commentId);

        return commentId;
    }

    /**
     * @dev Delete comments.
     *
     * Emits a {CommentsDeleted} event.
     */
    function deleteComments(uint256[] memory commentIdsParam) public {
        uint256 commentIdsParamMemVar = commentIdsParam.length;

        for (uint256 index = 0; index < commentIdsParamMemVar; index++) {
            uint256 currentCommentId = commentIdsParam[index];

            if ((msg.sender != creator) && (msg.sender != comments[currentCommentId].author)) {
                revert OnlyCreatorOrAuthorCanDeleteComments(currentCommentId);
            }

            if (!commentIsDeleted[currentCommentId]) {
                commentIsDeleted[currentCommentId] = true;
                deletedCommentIds.push(currentCommentId);
            }
        }

        emit CommentsDeleted(commentIdsParam);
    }
}

contract Contest is GovernorCountingSimple, GovernorModuleRegistry, GovernorEngagement {
    constructor(
        string memory _name,
        string memory _prompt,
        bytes32 _submissionMerkleRoot,
        bytes32 _votingMerkleRoot,
        ConstructorIntArgs memory _constructorIntArgs
    )
        Governor(_name, _prompt, _submissionMerkleRoot, _votingMerkleRoot, _constructorIntArgs)
        GovernorSorting(_constructorIntArgs.sortingEnabled, _constructorIntArgs.rankLimit)
    {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_prompt","type":"string"},{"internalType":"bytes32","name":"_submissionMerkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"_votingMerkleRoot","type":"bytes32"},{"components":[{"internalType":"uint256","name":"contestStart","type":"uint256"},{"internalType":"uint256","name":"votingDelay","type":"uint256"},{"internalType":"uint256","name":"votingPeriod","type":"uint256"},{"internalType":"uint256","name":"numAllowedProposalSubmissions","type":"uint256"},{"internalType":"uint256","name":"maxProposalCount","type":"uint256"},{"internalType":"uint256","name":"downvotingAllowed","type":"uint256"},{"internalType":"uint256","name":"sortingEnabled","type":"uint256"},{"internalType":"uint256","name":"rankLimit","type":"uint256"},{"internalType":"uint256","name":"percentageToCreator","type":"uint256"},{"internalType":"uint256","name":"costToPropose","type":"uint256"},{"internalType":"uint256","name":"costToVote","type":"uint256"}],"internalType":"struct Governor.ConstructorIntArgs","name":"_constructorIntArgs","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressNotPermissionedToSubmit","type":"error"},{"inputs":[{"internalType":"address","name":"author","type":"address"},{"internalType":"address","name":"sender","type":"address"}],"name":"AuthorIsNotSender","type":"error"},{"inputs":[],"name":"CannotDeleteWhenCompleted","type":"error"},{"inputs":[],"name":"CannotVoteOnDeletedProposal","type":"error"},{"inputs":[],"name":"ContestAlreadyCancelled","type":"error"},{"inputs":[{"internalType":"enum Governor.ContestState","name":"currentState","type":"uint8"}],"name":"ContestMustBeActiveToVote","type":"error"},{"inputs":[{"internalType":"enum Governor.ContestState","name":"currentState","type":"uint8"}],"name":"ContestMustBeQueuedToPropose","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxProposalCount","type":"uint256"}],"name":"ContestSubmissionLimitReached","type":"error"},{"inputs":[],"name":"DownvotingNotEnabled","type":"error"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"DuplicateSubmission","type":"error"},{"inputs":[],"name":"EmptyProposalDescription","type":"error"},{"inputs":[{"internalType":"uint256","name":"msgValue","type":"uint256"},{"internalType":"uint256","name":"costToVote","type":"uint256"}],"name":"IncorrectCostSent","type":"error"},{"inputs":[],"name":"IndexHasNotBeenPopulated","type":"error"},{"inputs":[],"name":"InvalidVoteType","type":"error"},{"inputs":[],"name":"MoreThanOneProposalWithThisManyVotes","type":"error"},{"inputs":[],"name":"NeedAtLeastOneVoteToVote","type":"error"},{"inputs":[],"name":"NeedToSubmitWithProofFirst","type":"error"},{"inputs":[],"name":"NeedToVoteWithProofFirst","type":"error"},{"inputs":[],"name":"NotEnoughVotesLeft","type":"error"},{"inputs":[],"name":"NotInMerkle","type":"error"},{"inputs":[],"name":"OnlyCreatorCanDelete","type":"error"},{"inputs":[],"name":"OnlyCreatorCanSetRewardsModule","type":"error"},{"inputs":[{"internalType":"uint256","name":"failedToDeleteCommentId","type":"uint256"}],"name":"OnlyCreatorOrAuthorCanDeleteComments","type":"error"},{"inputs":[],"name":"OnlyJkLabsCanAmend","type":"error"},{"inputs":[],"name":"OnlyJkLabsOrCreatorCanCancel","type":"error"},{"inputs":[],"name":"RankCannotBeZero","type":"error"},{"inputs":[],"name":"RankIsNotInSortedRanks","type":"error"},{"inputs":[{"internalType":"uint256","name":"numAllowedProposalSubmissions","type":"uint256"}],"name":"SenderSubmissionLimitReached","type":"error"},{"inputs":[{"internalType":"enum Governor.Metadatas","name":"unexpectedMetadata","type":"uint8"}],"name":"UnexpectedMetadata","type":"error"},{"inputs":[],"name":"ZeroSignersInSafeMetadata","type":"error"},{"inputs":[],"name":"ZeroThresholdInSafeMetadata","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"commentId","type":"uint256"}],"name":"CommentCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"commentIds","type":"uint256[]"}],"name":"CommentsDeleted","type":"event"},{"anonymous":false,"inputs":[],"name":"ContestCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"version","type":"string"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"prompt","type":"string"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"uint256","name":"contestStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"votingDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"votingPeriod","type":"uint256"}],"name":"JokeraceCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract RewardsModule","name":"oldOfficialRewardsModule","type":"address"},{"indexed":false,"internalType":"contract RewardsModule","name":"newOfficialRewardsModule","type":"address"}],"name":"OfficialRewardsModuleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"string","name":"proposalDescription","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"proposalIds","type":"uint256[]"}],"name":"ProposalsDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"numVotes","type":"uint256"}],"name":"VoteCast","type":"event"},{"inputs":[],"name":"AMOUNT_FOR_SUMBITTER_PROOF","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"JK_LABS_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"METADATAS_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressSubmitterVerified","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressTotalCastVoteCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressTotalVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressTotalVotesVerified","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"addressesThatHaveVoted","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allProposalTotalVotes","outputs":[{"internalType":"uint256[]","name":"proposalIdsReturn","type":"uint256[]"},{"components":[{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"againstVotes","type":"uint256"}],"internalType":"struct GovernorCountingSimple.VoteCounts[]","name":"proposalVoteCountsArrayReturn","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"canceled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint256","name":"totalVotes","type":"uint256"},{"internalType":"uint256","name":"numVotes","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"castVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"uint256","name":"numVotes","type":"uint256"}],"name":"castVoteWithoutProof","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addressToCheck","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bool","name":"voting","type":"bool"}],"name":"checkProof","outputs":[{"internalType":"bool","name":"verified","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"string","name":"commentContent","type":"string"}],"name":"comment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"commentIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"commentIsDeleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"comments","outputs":[{"internalType":"address","name":"author","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"string","name":"commentContent","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"contestAddressTotalVotesCast","outputs":[{"internalType":"uint256","name":"userTotalVotesCast","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contestDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contestStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"costToPropose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"costToVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"commentIdsParam","type":"uint256[]"}],"name":"deleteComments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"proposalIdsToDelete","type":"uint256[]"}],"name":"deleteProposals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deletedCommentIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deletedProposalIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"downvotingAllowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"forVotesToProposalIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllAddressesThatHaveVoted","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllAuthorsOfDeletedProposals","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllCommentIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllDeletedCommentIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllDeletedProposalIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllProposalAuthors","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllProposalIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"commentId","type":"uint256"}],"name":"getComment","outputs":[{"components":[{"internalType":"address","name":"author","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"string","name":"commentContent","type":"string"}],"internalType":"struct GovernorEngagement.CommentCore","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"forVotes","type":"uint256"}],"name":"getNumProposalsWithThisManyForVotes","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"forVotes","type":"uint256"}],"name":"getOnlyProposalIdWithThisManyForVotes","outputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"getProposal","outputs":[{"components":[{"internalType":"address","name":"author","type":"address"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"address","name":"targetAddress","type":"address"}],"internalType":"struct Governor.TargetMetadata","name":"targetMetadata","type":"tuple"},{"components":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"internalType":"struct Governor.SafeMetadata","name":"safeMetadata","type":"tuple"}],"internalType":"struct Governor.ProposalCore","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"getProposalComments","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"forVotes","type":"uint256"}],"name":"getProposalsWithThisManyForVotes","outputs":[{"internalType":"uint256[]","name":"proposalsWithThisManyForVotes","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rank","type":"uint256"}],"name":"getRankIndex","outputs":[{"internalType":"uint256","name":"rankIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSortedRanks","outputs":[{"internalType":"uint256[]","name":"sortedRanksArray","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"author","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"string","name":"commentContent","type":"string"}],"internalType":"struct GovernorEngagement.CommentCore","name":"commentObj","type":"tuple"}],"name":"hashComment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"author","type":"address"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"address","name":"targetAddress","type":"address"}],"internalType":"struct Governor.TargetMetadata","name":"targetMetadata","type":"tuple"},{"components":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"internalType":"struct Governor.SafeMetadata","name":"safeMetadata","type":"tuple"}],"internalType":"struct Governor.ProposalCore","name":"proposal","type":"tuple"}],"name":"hashProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"idx","type":"uint256"}],"name":"isOrIsBelowTiedRank","outputs":[{"internalType":"bool","name":"atOrBelowTiedRank","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxProposalCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numAllowedProposalSubmissions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numSubmissions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"officialRewardsModule","outputs":[{"internalType":"contract RewardsModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"percentageToCreator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prompt","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"}],"name":"proposalAddressVotes","outputs":[{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"againstVotes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalAddressesHaveVoted","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposalAuthors","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposalComments","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposalIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposalIsDeleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalVotes","outputs":[{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"againstVotes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposalVotesStructs","outputs":[{"components":[{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"againstVotes","type":"uint256"}],"internalType":"struct GovernorCountingSimple.VoteCounts","name":"proposalVoteCounts","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"address","name":"author","type":"address"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"address","name":"targetAddress","type":"address"}],"internalType":"struct Governor.TargetMetadata","name":"targetMetadata","type":"tuple"},{"components":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"internalType":"struct Governor.SafeMetadata","name":"safeMetadata","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"author","type":"address"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"address","name":"targetAddress","type":"address"}],"internalType":"struct Governor.TargetMetadata","name":"targetMetadata","type":"tuple"},{"components":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"internalType":"struct Governor.SafeMetadata","name":"safeMetadata","type":"tuple"}],"internalType":"struct Governor.ProposalCore","name":"proposal","type":"tuple"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"author","type":"address"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"address","name":"targetAddress","type":"address"}],"internalType":"struct Governor.TargetMetadata","name":"targetMetadata","type":"tuple"},{"components":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"internalType":"struct Governor.SafeMetadata","name":"safeMetadata","type":"tuple"}],"internalType":"struct Governor.ProposalCore","name":"proposal","type":"tuple"}],"name":"proposeWithoutProof","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"rankLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract RewardsModule","name":"officialRewardsModule_","type":"address"}],"name":"setOfficialRewardsModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newSubmissionMerkleRoot","type":"bytes32"}],"name":"setSubmissionMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newVotingMerkleRoot","type":"bytes32"}],"name":"setVotingMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"sortedRanks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sortingEnabled","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Governor.ContestState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"submissionMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalVotesCast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"author","type":"address"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"string","name":"description","type":"string"},{"components":[{"internalType":"address","name":"targetAddress","type":"address"}],"internalType":"struct Governor.TargetMetadata","name":"targetMetadata","type":"tuple"},{"components":[{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"internalType":"struct Governor.SafeMetadata","name":"safeMetadata","type":"tuple"}],"internalType":"struct Governor.ProposalCore","name":"proposal","type":"tuple"}],"name":"validateProposalData","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"verifyProposer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"totalVotes","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"verifyVoter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"voteStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

Deployed Bytecode

0x6080604052600436106104935760003560e01c8063711effc811610260578063c19d93fb11610144578063ea8a1af0116100c1578063f4f3d7ec11610085578063f4f3d7ec14610e6c578063f5c3641114610e8c578063f61736f414610eac578063f79c017214610ecc578063fb8ddab414610efc578063fb9bf8d414610f1c57600080fd5b8063ea8a1af014610de4578063edcd1be414610df9578063eef18e1714610e0f578063efa90d3614610e37578063f0a7db0a14610e4c57600080fd5b8063daf762db11610108578063daf762db14610d57578063dd96a19d14610d77578063dea5f6a614610d8d578063e031535b14610dba578063e11db9d814610dcf57600080fd5b8063c19d93fb14610ca3578063c7f758a814610cc5578063c9a1b6b214610cf2578063cb85395014610d12578063cbdc27cb14610d4257600080fd5b80639b644a23116101dd578063aec116b6116101a1578063aec116b614610be4578063b323580d14610c1a578063b66d1da314610c3a578063bddc164114610c5a578063c05f410414610c70578063c0ffaa7814610c9057600080fd5b80639b644a2314610b1a5780639ba197af14610b3a578063a1ac6cb214610b67578063ac67f80114610b94578063ae66b8ad14610bb457600080fd5b8063832009af11610224578063832009af14610a6f5780638ebb4c1514610a855780639174778c14610ab5578063930de97914610ad5578063946369b514610b0557600080fd5b8063711effc8146109d757806375e509c5146109f7578063785ddfe514610a245780637c65d71114610a445780637de418d514610a5957600080fd5b80633f9942ff11610387578063531bd812116103045780635cb718a1116102c85780635cb718a11461094e57806360506ff61461096357806365f16263146109795780636e4eb8101461098c5780636ed815ad146109ac5780636fd3636b146109c257600080fd5b8063531bd81214610877578063544c7bb414610897578063544ffc9c146108b757806354fd4d50146109015780635c7107d81461092e57600080fd5b8063476f4d8a1161034b578063476f4d8a146107f65780634d24a67f1461080957806350a5e5241461081e57806350c4b6161461084157806351a41dec1461086157600080fd5b80633f9942ff146107695780633fb57c9214610783578063409fd030146107a3578063419c533c146107c3578063458da87d146107d657600080fd5b80631242b73711610415578063325cc6d9116103d9578063325cc6d9146106d157806332763c22146106f1578063347cf66514610721578063366ecf5b1461073d5780633932abb11461075357600080fd5b80631242b737146106365780631805c5231461065857806320b3e84514610678578063262e59e91461069a5780632c39805f146106af57600080fd5b806305846cae1161045c57806305846cae1461055657806306fdde0314610576578063070dc5d9146105985780630800e300146105e95780630aa25e441461061657600080fd5b80624114a814610498578063013cf08b146104c157806302a251a3146104f257806302d05d3f146105085780630414126a14610540575b600080fd5b3480156104a457600080fd5b506104ae60085481565b6040519081526020015b60405180910390f35b3480156104cd57600080fd5b506104e16104dc36600461375b565b610f32565b6040516104b8959493929190613813565b3480156104fe57600080fd5b506104ae600a5481565b34801561051457600080fd5b50600754610528906001600160a01b031681565b6040516001600160a01b0390911681526020016104b8565b34801561054c57600080fd5b506104ae60015481565b34801561056257600080fd5b506104ae61057136600461375b565b61107a565b34801561058257600080fd5b5061058b61109b565b6040516104b89190613858565b3480156105a457600080fd5b506105dc6105b336600461375b565b601e60209081526000918252604091829020825180840190935280548352600101549082015281565b6040516104b8919061386b565b3480156105f557600080fd5b5061060961060436600461375b565b611129565b6040516104b89190613882565b34801561062257600080fd5b5061052861063136600461375b565b61123d565b34801561064257600080fd5b5061064b611267565b6040516104b89190613906565b34801561066457600080fd5b506104ae610673366004613a3a565b6112bf565b34801561068457600080fd5b50610698610693366004613ad9565b6113e0565b005b3480156106a657600080fd5b506104ae61144f565b3480156106bb57600080fd5b506106c461146b565b6040516104b89190613b2d565b3480156106dd57600080fd5b506104ae6106ec36600461375b565b6114cc565b3480156106fd57600080fd5b5061071161070c366004613b8f565b6114dc565b60405190151581526020016104b8565b34801561072d57600080fd5b506104ae678ac7230489e8000081565b34801561074957600080fd5b506104ae60005481565b34801561075f57600080fd5b506104ae60095481565b34801561077557600080fd5b506014546107119060ff1681565b34801561078f57600080fd5b506104ae61079e36600461375b565b6115db565b3480156107af57600080fd5b506104ae6107be366004613bff565b6115eb565b6104ae6107d1366004613cbb565b61161c565b3480156107e257600080fd5b506104ae6107f1366004613eca565b61168c565b6104ae610804366004613f16565b61169f565b34801561081557600080fd5b506104ae611718565b34801561082a57600080fd5b50610833611726565b6040516104b8929190613f4a565b34801561084d57600080fd5b5061052861085c36600461375b565b61182c565b34801561086d57600080fd5b506104ae60105481565b34801561088357600080fd5b50610698610892366004613fb3565b61183c565b3480156108a357600080fd5b506106986108b236600461375b565b6118a2565b3480156108c357600080fd5b506108ec6108d236600461375b565b6000908152601e6020526040902080546001909101549091565b604080519283526020830191909152016104b8565b34801561090d57600080fd5b506040805180820190915260048152630d0b8c8d60e21b602082015261058b565b34801561093a57600080fd5b506104ae61094936600461375b565b6118db565b34801561095a57600080fd5b5061064b6119e2565b34801561096f57600080fd5b506104ae600d5481565b6104ae61098736600461400e565b611a38565b34801561099857600080fd5b506108ec6109a7366004614043565b611ad2565b3480156109b857600080fd5b506104ae600f5481565b3480156109ce57600080fd5b5061064b611b07565b3480156109e357600080fd5b506104ae6109f2366004614073565b611b5d565b348015610a0357600080fd5b506104ae610a12366004614095565b60166020526000908152604090205481565b348015610a3057600080fd5b50602054610528906001600160a01b031681565b348015610a5057600080fd5b5061058b611b8e565b348015610a6557600080fd5b506104ae601c5481565b348015610a7b57600080fd5b506104ae600b5481565b348015610a9157600080fd5b50610aa5610aa036600461375b565b611b9b565b6040516104b894939291906140b2565b348015610ac157600080fd5b50610711610ad036600461375b565b611c58565b348015610ae157600080fd5b50610711610af0366004614095565b601a6020526000908152604090205460ff1681565b348015610b1157600080fd5b506106c4611cfe565b348015610b2657600080fd5b506104ae610b3536600461375b565b611d5e565b348015610b4657600080fd5b506104ae610b5536600461375b565b6000908152601f602052604090205490565b348015610b7357600080fd5b506104ae610b82366004614095565b601d6020526000908152604090205481565b348015610ba057600080fd5b50610698610baf3660046140df565b611d6e565b348015610bc057600080fd5b50610711610bcf36600461375b565b60256020526000908152604090205460ff1681565b348015610bf057600080fd5b506104ae610bff366004614095565b6001600160a01b03166000908152601d602052604090205490565b348015610c2657600080fd5b506106c4610c3536600461375b565b611ea8565b348015610c4657600080fd5b506104ae610c5536600461375b565b611f1a565b348015610c6657600080fd5b506104ae60035481565b348015610c7c57600080fd5b5061064b610c8b36600461375b565b611f7a565b6104ae610c9e36600461416f565b611fdc565b348015610caf57600080fd5b50610cb8612024565b6040516104b891906141e0565b348015610cd157600080fd5b50610ce5610ce036600461375b565b612075565b6040516104b891906141fa565b348015610cfe57600080fd5b5061064b610d0d36600461375b565b6121ef565b348015610d1e57600080fd5b50610711610d2d366004614095565b601b6020526000908152604090205460ff1681565b348015610d4e57600080fd5b506106c461224f565b348015610d6357600080fd5b50610698610d7236600461375b565b61237f565b348015610d8357600080fd5b506104ae60045481565b348015610d9957600080fd5b506104ae610da8366004614095565b60196020526000908152604090205481565b348015610dc657600080fd5b506104ae6123b8565b348015610ddb57600080fd5b5061064b6123ca565b348015610df057600080fd5b50610698612420565b348015610e0557600080fd5b506104ae600e5481565b348015610e1b57600080fd5b5061052873dc652c746a8f85e18ce632d97c6118e8a52fa73881565b348015610e4357600080fd5b5061064b6124e4565b348015610e5857600080fd5b50610698610e67366004614261565b61253a565b348015610e7857600080fd5b50610698610e87366004614095565b612695565b348015610e9857600080fd5b506104ae610ea736600461375b565b612715565b348015610eb857600080fd5b506104ae610ec7366004614073565b612725565b348015610ed857600080fd5b50610711610ee736600461375b565b60136020526000908152604090205460ff1681565b348015610f0857600080fd5b50610698610f17366004613eca565b612741565b348015610f2857600080fd5b506104ae600c5481565b601560205260009081526040902080546001820180546001600160a01b03831693600160a01b90930460ff16929190610f6a906142a2565b80601f0160208091040260200160405190810160405280929190818152602001828054610f96906142a2565b8015610fe35780601f10610fb857610100808354040283529160200191610fe3565b820191906000526020600020905b815481529060010190602001808311610fc657829003601f168201915b5050604080516020808201835260028801546001600160a01b03168252825160038901805460609381028301840186529482018581529899939893975090955093508492849184018282801561106257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611044575b50505050508152602001600182015481525050905085565b6012818154811061108a57600080fd5b600091825260209091200154905081565b600580546110a8906142a2565b80601f01602080910402602001604051908101604052809291908181526020018280546110d4906142a2565b80156111215780601f106110f657610100808354040283529160200191611121565b820191906000526020600020905b81548152906001019060200180831161110457829003601f168201915b505050505081565b61115d604051806080016040528060006001600160a01b031681526020016000815260200160008152602001606081525090565b600082815260236020908152604091829020825160808101845281546001600160a01b031681526001820154928101929092526002810154928201929092526003820180549192916060840191906111b4906142a2565b80601f01602080910402602001604051908101604052809291908181526020018280546111e0906142a2565b801561122d5780601f106112025761010080835404028352916020019161122d565b820191906000526020600020905b81548152906001019060200180831161121057829003601f168201915b5050505050815250509050919050565b6017818154811061124d57600080fd5b6000918252602090912001546001600160a01b0316905081565b606060128054806020026020016040519081016040528092919081815260200182805480156112b557602002820191906000526020600020905b8154815260200190600101908083116112a1575b5050505050905090565b6040805160808101825233815242602082015290810183905260608101829052600090816112ec826115eb565b6021805460018082019092557f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001829055600082815260236020908152604091829020865181546001600160a01b0319166001600160a01b03909116178155908601519281019290925584015160028201556060840151919250839160038201906113779082614324565b505050600085815260246020908152604080832080546001810182559084529190922001829055517f5a1a930fed43f34b3a07db782ebcac28a661c273e662bb98458cfba5a8ccd220906113ce9083815260200190565b60405180910390a19150505b92915050565b6001600160a01b0383166000908152601b602052604090205460ff1661144a5760035460000361140f57505050565b61142583678ac7230489e80000848460006114dc565b506001600160a01b0383166000908152601b60205260409020805460ff191660011790555b505050565b6000600a5461145c6123b8565b61146691906143f9565b905090565b606060188054806020026020016040519081016040528092919081815260200182805480156112b557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116114a5575050505050905090565b6002818154811061108a57600080fd5b6040516bffffffffffffffffffffffff19606087901b16602082015260348101859052600090819060540160405160208183030381529060405280519060200120905060008361156c57611567868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506003549150859050612890565b6115ad565b6115ad868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506004549150859050612890565b9050806115cd5760405163452c2df160e11b815260040160405180910390fd5b506001979650505050505050565b6022818154811061108a57600080fd5b6000816040516020016115fe9190613882565b60408051601f19818403018152919052805160209091012092915050565b60008061162960016128a6565b600089815260136020526040902054909150339060ff161561165e576040516358f1119560e01b815260040160405180910390fd5b61166a8188878761183c565b61167382612919565b61167f89828a89612a2f565b9998505050505050505050565b6000816040516020016115fe91906141fa565b6000806116ac60006128a6565b600354909150156116e757336000908152601b602052604090205460ff166116e757604051631f22097560e01b815260040160405180910390fd5b6116f3610f178461440c565b60006117066117018561440c565b612b76565b905061171182612919565b9392505050565b6117236001806143f9565b81565b60608060006117336124e4565b9050600081516001600160401b0381111561175057611750613919565b60405190808252806020026020018201604052801561179557816020015b604080518082019091526000808252602082015281526020019060019003908161176e5790505b50905060005b825181101561182257601e60008483815181106117ba576117ba614418565b602002602001015181526020019081526020016000206000016040518060400160405290816000820154815260200160018201548152505082828151811061180457611804614418565b6020026020010181905250808061181a9061442e565b91505061179b565b5090939092509050565b6018818154811061124d57600080fd5b6001600160a01b0384166000908152601a602052604090205460ff1661189c5761186a8484848460016114dc565b506001600160a01b0384166000908152601960209081526040808320869055601a9091529020805460ff191660011790555b50505050565b3373dc652c746a8f85e18ce632d97c6118e8a52fa738146118d65760405163de07280160e01b815260040160405180910390fd5b600455565b6000816000036118fe57604051630ec90a1760e31b815260040160405180910390fd5b6002805460408051602080840282018101909252828152919260009291849083018282801561194c57602002820191906000526020600020905b815481526020019060010190808311611938575b5050505050905060006001905060005b838110156119c85761199383828151811061197957611979614418565b60200260200101516000908152601f602052604090205490565b156119b6578582036119a85795945050505050565b816119b28161442e565b9250505b806119c08161442e565b91505061195c565b50604051632cc2ab7360e11b815260040160405180910390fd5b606060228054806020026020016040519081016040528092919081815260200182805480156112b557602002820191906000526020600020908154815260200190600101908083116112a1575050505050905090565b600080611a4560016128a6565b600086815260136020526040902054909150339060ff1615611a7a576040516358f1119560e01b815260040160405180910390fd5b6001600160a01b0381166000908152601a602052604090205460ff16611ab35760405163126ec6d160e31b815260040160405180910390fd5b611abc82612919565b611ac886828787612a2f565b9695505050505050565b6000828152601e602090815260408083206001600160a01b0385168452600301909152902080546001909101545b9250929050565b606060028054806020026020016040519081016040528092919081815260200182805480156112b557602002820191906000526020600020908154815260200190600101908083116112a1575050505050905090565b601f6020528160005260406000208181548110611b7957600080fd5b90600052602060002001600091509150505481565b600680546110a8906142a2565b60236020526000908152604090208054600182015460028301546003840180546001600160a01b03909416949293919291611bd5906142a2565b80601f0160208091040260200160405190810160405280929190818152602001828054611c01906142a2565b8015611c4e5780601f10611c2357610100808354040283529160200191611c4e565b820191906000526020600020905b815481529060010190602001808311611c3157829003601f168201915b5050505050905084565b600254600090611c6a90600190614447565b821115611c8a576040516365d6f35160e11b815260040160405180910390fd5b60005b611c988360016143f9565b811015611cf5576001611cd460028381548110611cb757611cb7614418565b90600052602060002001546000908152601f602052604090205490565b1115611ce35750600192915050565b80611ced8161442e565b915050611c8d565b50600092915050565b606060178054806020026020016040519081016040528092919081815260200182805480156112b5576020028201919060005260206000209081546001600160a01b031681526001909101906020018083116114a5575050505050905090565b6011818154811061108a57600080fd5b805160005b81811015611e6c576000838281518110611d8f57611d8f614418565b60209081029190910101516007549091506001600160a01b03163314801590611dcf57506000818152602360205260409020546001600160a01b03163314155b15611df557604051635450763d60e11b8152600481018290526024015b60405180910390fd5b60008181526025602052604090205460ff16611e59576000818152602560205260408120805460ff191660019081179091556022805491820181559091527f61035b26e3e9eee00e0d72fd1ee8ddca6894550dca6916ea2ac6baa90d11e510018190555b5080611e648161442e565b915050611d73565b507f788a4349d25bc08585923ae212bce8bb346a623bce753eeecb85fd9ce58dcb4b82604051611e9c9190613906565b60405180910390a15050565b6000818152601e60209081526040918290206002810180548451818502810185019095528085526060949293830182828015611f0d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611eef575b5050505050915050919050565b6000818152601f6020526040812054600114611f4957604051633832a15560e21b815260040160405180910390fd5b6000828152601f602052604081208054909190611f6857611f68614418565b90600052602060002001549050919050565b600081815260246020908152604091829020805483518184028101840190945280845260609392830182828015611fd057602002820191906000526020600020905b815481526020019060010190808311611fbc575b50505050509050919050565b600080611fe960006128a6565b9050611ff63385856113e0565b612002610f178661440c565b60006120106117018761440c565b905061201b82612919565b95945050505050565b60145460009060ff16156120385750600290565b42600854106120475750600090565b426120506123b8565b1061205b5750600390565b4261206461144f565b1061206f5750600190565b50600490565b61207d613670565b600082815260156020908152604091829020825160a08101845281546001600160a01b0381168252600160a01b900460ff1615159281019290925260018101805492939192918401916120cf906142a2565b80601f01602080910402602001604051908101604052809291908181526020018280546120fb906142a2565b80156121485780601f1061211d57610100808354040283529160200191612148565b820191906000526020600020905b81548152906001019060200180831161212b57829003601f168201915b5050509183525050604080516020818101835260028501546001600160a01b031682528084019190915281516003850180546060938102830184018552828501818152949095019491939092849284918401828280156121d157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116121b3575b50505050508152602001600182015481525050815250509050919050565b6000818152601f6020908152604091829020805483518184028101840190945280845260609392830182828015611fd05760200282019190600052602060002090815481526020019060010190808311611fbc5750505050509050919050565b60606000601280548060200260200160405190810160405280929190818152602001828054801561229f57602002820191906000526020600020905b81548152602001906001019080831161228b575b50505050509050600081516001600160401b038111156122c1576122c1613919565b6040519080825280602002602001820160405280156122ea578160200160208202803683370190505b50905060005b8251811015612378576015600084838151811061230f5761230f614418565b6020026020010151815260200190815260200160002060000160009054906101000a90046001600160a01b031682828151811061234e5761234e614418565b6001600160a01b0390921660209283029190910190910152806123708161442e565b9150506122f0565b5092915050565b3373dc652c746a8f85e18ce632d97c6118e8a52fa738146123b35760405163de07280160e01b815260040160405180910390fd5b600355565b600060095460085461146691906143f9565b606060218054806020026020016040519081016040528092919081815260200182805480156112b557602002820191906000526020600020908154815260200190600101908083116112a1575050505050905090565b6007546001600160a01b0316331480159061244f57503373dc652c746a8f85e18ce632d97c6118e8a52fa73814155b1561246d576040516301dbf46f60e71b815260040160405180910390fd5b6000612477612024565b9050600281600481111561248d5761248d6141ca565b036124ab57604051633c30acbf60e01b815260040160405180910390fd5b6014805460ff191660011790556040517f4cd963a081760a54f571abc0f1db4dde31b4a07d8d6da3e844b8c6f47eeaaa4290600090a150565b606060118054806020026020016040519081016040528092919081815260200182805480156112b557602002820191906000526020600020908154815260200190600101908083116112a1575050505050905090565b6007546001600160a01b031633146125655760405163b8d4540960e01b815260040160405180910390fd5b600461256f612024565b6004811115612580576125806141ca565b0361259e576040516331da1c8b60e11b815260040160405180910390fd5b60005b818110156126435760008383838181106125bd576125bd614418565b60209081029290920135600081815260139093526040909220549192505060ff16612630576000818152601360205260408120805460ff191660019081179091556012805491820181559091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec3444018190555b508061263b8161442e565b9150506125a1565b50600d5415801561265657506000546001145b15612665576126658282612df4565b7f75a75cf5c561892f4cc5b26c1b8e933849b42238c96dd073d080d1ae96c514166011604051611e9c919061445a565b6007546001600160a01b031633146126c057604051630f4cb1bd60e11b815260040160405180910390fd5b602080546001600160a01b038381166001600160a01b03198316811784556040805192909316808352938201527f753a2cf8d360cff631674504210913e48247f8e56b3e6d2006c2103d4095999f9101611e9c565b6021818154811061108a57600080fd5b60246020528160005260406000208181548110611b7957600080fd5b80516001600160a01b0316331461277f57805160405163fbbf4d7f60e01b81526001600160a01b039091166004820152336024820152604401611dec565b60005b61278d6001806143f9565b8110156128665760008160018111156127a8576127a86141ca565b905060008160018111156127be576127be6141ca565b036127c95750612854565b60018160018111156127dd576127dd6141ca565b0361283757608083015151516000036128095760405163c3b2798b60e01b815260040160405180910390fd5b826080015160200151600003612832576040516392fb9a3560e01b815260040160405180910390fd5b612852565b8060405163d2277d4960e01b8152600401611dec9190614495565b505b8061285e8161442e565b915050612782565b5080604001515160000361288d5760405163e182473360e01b815260040160405180910390fd5b50565b60008261289d8584612e51565b14949350505050565b600080808360018111156128bc576128bc6141ca565b036128ca5750600f546128f0565b60018360018111156128de576128de6141ca565b036128ec57506010546128f0565b5060005b8034146113da576040516372c3eaa760e01b815234600482015260248101829052604401611dec565b801561288d5760006064600e5460646129329190614447565b61293c90346144a9565b61294691906144c0565b905080156129ba5761296c73dc652c746a8f85e18ce632d97c6118e8a52fa73882612e9e565b6040805173dc652c746a8f85e18ce632d97c6118e8a52fa7388152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a15b60006129c68234614447565b9050801561144a576007546129e4906001600160a01b031682612e9e565b600754604080516001600160a01b039092168252602082018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b60006001612a3b612024565b6004811115612a4c57612a4c6141ca565b14612a7357612a59612024565b60405163049cab4960e51b8152600401611dec91906141e0565b81600003612a945760405163502e1c2960e01b815260040160405180910390fd5b612ac685858585601960008a6001600160a01b03166001600160a01b0316815260200190815260200160002054612fb7565b601880546001810182556000919091527fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e0180546001600160a01b031916331790556040805186815260ff851660208201529081018390526001600160a01b038516907f2c9deb38f462962eadbd85a9d3a4120503ee091f1582eaaa10aa8c6797651d299060600160405180910390a25050506001600160a01b0316600090815260196020526040902054919050565b60006003612b82612024565b6004811115612b9357612b936141ca565b14612bba57612ba0612024565b604051632889531360e01b8152600401611dec91906141e0565b600b543360009081526016602052604090205403612bf157600b54604051632bd6d93960e21b8152600401611dec91815260200190565b600c54601254601154612c049190614447565b03612c2857600c546040516302217f5360e51b8152600401611dec91815260200190565b6000612c338361168c565b600081815260156020526040902054909150600160a01b900460ff1615612c705760405163baffc42360e01b815260048101829052602401611dec565b6011805460018181019092557f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680182905560008281526015602090815260409182902086518154928801511515600160a01b026001600160a81b03199093166001600160a01b0390911617919091178155908501518592820190612cf49082614324565b506060820151516002820180546001600160a01b0319166001600160a01b039092169190911790556080820151805180516003840191612d39918391602001906136e1565b5060209182015160019182015533600090815260169092526040822080549194509250612d679084906143f9565b9091555050601780546001810182556000919091527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c150180546001600160a01b0319163390811790915560408085015190517f7585f467599d0f008985f231af99293be388626ac16ca59505c2f8f88969cd6392612de69285926144e2565b60405180910390a192915050565b60005b8181101561144a576000838383818110612e1357612e13614418565b602090810292909201356000818152601e909352604090922054919250612e3c9050828261321e565b50508080612e499061442e565b915050612df7565b600081815b8451811015612e9657612e8282868381518110612e7557612e75614418565b602002602001015161334f565b915080612e8e8161442e565b915050612e56565b509392505050565b80471015612eee5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401611dec565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612f3b576040519150601f19603f3d011682016040523d82523d6000602084013e612f40565b606091505b505090508061144a5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401611dec565b6000858152601e602090815260408083206001600160a01b0388168452601d90925290912054612fe79083614447565b8311156130075760405163660fa07360e11b815260040160405180910390fd5b6001600160a01b038516600090815260038201602052604081205415801561304a57506001600160a01b0386166000908152600383016020526040902060010154155b905060ff85166130a2578154849083906000906130689084906143f9565b90915550506001600160a01b0386166000908152600383016020526040812080548692906130979084906143f9565b909155506131339050565b60001960ff86160161311a57600d546001146130d157604051639755958f60e01b815260040160405180910390fd5b838260000160010160008282546130e891906143f9565b90915550506001600160a01b0386166000908152600383016020526040812060010180548692906130979084906143f9565b604051638eed55d160e01b815260040160405180910390fd5b801561316a57600282018054600181018255600091825260209091200180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b0386166000908152601d6020526040812080548692906131929084906143f9565b9250508190555083601c60008282546131ab91906143f9565b9091555050600d541580156131c257506000546001145b1561321557815460006131d58683614447565b905080156131e7576131e7898261321e565b6000828152601f6020908152604082208054600181018255908352912001899055613212818361337b565b50505b50505050505050565b6000818152601f602090815260408083208054825181850281018501909352808352919290919083018282801561327457602002820191906000526020600020905b815481526020019060010190808311613260575b5050505050905060005b815181101561189c578382828151811061329a5761329a614418565b60200260200101510361333d5781600183516132b69190614447565b815181106132c6576132c6614418565b6020026020010151601f600085815260200190815260200160002082815481106132f2576132f2614418565b9060005260206000200181905550601f60008481526020019081526020016000208054806133225761332261450c565b6001900381819060005260206000200160009055905561189c565b806133478161442e565b91505061327e565b600081831061336b576000828152602084905260409020611711565b5060009182526020526040902090565b600280546040805160208084028201810190925282815291926000929184908301828280156133c957602002820191906000526020600020905b8154815260200190600101908083116133b5575b5050505050905081600003613410575050600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace015550565b8061341c600184614447565b8151811061342c5761342c614418565b602002602001015183101561348257600154820361344a5750505050565b5050600280546001810182556000919091527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace015550565b61189c848484846000805b838110156134f7578281815181106134a7576134a7614418565b602002602001015185036134bc57505061189c565b8281815181106134ce576134ce614418565b60200260200101518511156134e5578091506134f7565b806134ef8161442e565b91505061348d565b506000808611801561351557506000868152601f6020526040902054155b9050600081801561353e57508684848151811061353457613534614418565b6020026020010151145b6136475761354d600186614447565b83146135f55760006135608460016143f9565b90505b858110156135f35784613577600183614447565b8151811061358757613587614418565b6020026020010151600282815481106135a2576135a2614418565b6000918252602090912001558280156135d35750878582815181106135c9576135c9614418565b6020026020010151145b156135e157600191506135f3565b806135eb8161442e565b915050613563565b505b80158015613604575060015485105b1561364757600284613617600188614447565b8151811061362757613627614418565b602090810291909101810151825460018101845560009384529190922001555b856002848154811061365b5761365b614418565b60009182526020909120015550505050505050565b6040518060a0016040528060006001600160a01b03168152602001600015158152602001606081526020016136ba604051806020016040528060006001600160a01b031681525090565b81526020016136dc604051806040016040528060608152602001600081525090565b905290565b828054828255906000526020600020908101928215613736579160200282015b8281111561373657825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613701565b50613742929150613746565b5090565b5b808211156137425760008155600101613747565b60006020828403121561376d57600080fd5b5035919050565b6000815180845260005b8181101561379a5760208185018101518683018201520161377e565b506000602082860101526020601f19601f83011685010191505092915050565b805160408084528151908401819052600091602091908201906060860190845b818110156137ff5783516001600160a01b0316835292840192918401916001016137da565b505093820151949091019390935250919050565b600060018060a01b038088168352861515602084015260a0604084015261383d60a0840187613774565b818651166060850152838103608085015261167f81866137ba565b6020815260006117116020830184613774565b8151815260208083015190820152604081016113da565b6020815260018060a01b0382511660208201526020820151604082015260408201516060820152600060608301516080808401526138c360a0840182613774565b949350505050565b600081518084526020808501945080840160005b838110156138fb578151875295820195908201906001016138df565b509495945050505050565b60208152600061171160208301846138cb565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561395157613951613919565b60405290565b60405160a081016001600160401b038111828210171561395157613951613919565b604051602081016001600160401b038111828210171561395157613951613919565b604051601f8201601f191681016001600160401b03811182821017156139c3576139c3613919565b604052919050565b600082601f8301126139dc57600080fd5b81356001600160401b038111156139f5576139f5613919565b613a08601f8201601f191660200161399b565b818152846020838601011115613a1d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613a4d57600080fd5b8235915060208301356001600160401b03811115613a6a57600080fd5b613a76858286016139cb565b9150509250929050565b6001600160a01b038116811461288d57600080fd5b60008083601f840112613aa757600080fd5b5081356001600160401b03811115613abe57600080fd5b6020830191508360208260051b8501011115611b0057600080fd5b600080600060408486031215613aee57600080fd5b8335613af981613a80565b925060208401356001600160401b03811115613b1457600080fd5b613b2086828701613a95565b9497909650939450505050565b6020808252825182820181905260009190848201906040850190845b81811015613b6e5783516001600160a01b031683529284019291840191600101613b49565b50909695505050505050565b80358015158114613b8a57600080fd5b919050565b600080600080600060808688031215613ba757600080fd5b8535613bb281613a80565b94506020860135935060408601356001600160401b03811115613bd457600080fd5b613be088828901613a95565b9094509250613bf3905060608701613b7a565b90509295509295909350565b600060208284031215613c1157600080fd5b81356001600160401b0380821115613c2857600080fd5b9083019060808286031215613c3c57600080fd5b604051608081018181108382111715613c5757613c57613919565b6040528235613c6581613a80565b808252506020830135602082015260408301356040820152606083013582811115613c8f57600080fd5b613c9b878286016139cb565b60608301525095945050505050565b803560ff81168114613b8a57600080fd5b60008060008060008060a08789031215613cd457600080fd5b86359550613ce460208801613caa565b9450604087013593506060870135925060808701356001600160401b03811115613d0d57600080fd5b613d1989828a01613a95565b979a9699509497509295939492505050565b60006001600160401b03821115613d4457613d44613919565b5060051b60200190565b600060408284031215613d6057600080fd5b613d6861392f565b905081356001600160401b03811115613d8057600080fd5b8201601f81018413613d9157600080fd5b80356020613da6613da183613d2b565b61399b565b82815260059290921b83018101918181019087841115613dc557600080fd5b938201935b83851015613dec578435613ddd81613a80565b82529382019390820190613dca565b85525093840135938301939093525092915050565b600081830360a0811215613e1457600080fd5b613e1c613957565b91508235613e2981613a80565b8252613e3760208401613b7a565b602083015260408301356001600160401b0380821115613e5657600080fd5b613e62868387016139cb565b60408501526020605f1984011215613e7957600080fd5b613e81613979565b925060608501359150613e9382613a80565b8183528260608501526080850135925080831115613eb057600080fd5b5050613ebe84828501613d4e565b60808301525092915050565b600060208284031215613edc57600080fd5b81356001600160401b03811115613ef257600080fd5b6138c384828501613e01565b600060a08284031215613f1057600080fd5b50919050565b600060208284031215613f2857600080fd5b81356001600160401b03811115613f3e57600080fd5b6138c384828501613efe565b60006040808352613f5d818401866138cb565b83810360208581019190915285518083528682019282019060005b81811015613fa557613f9583865180518252602090810151910152565b9383019391850191600101613f78565b509098975050505050505050565b60008060008060608587031215613fc957600080fd5b8435613fd481613a80565b93506020850135925060408501356001600160401b03811115613ff657600080fd5b61400287828801613a95565b95989497509550505050565b60008060006060848603121561402357600080fd5b8335925061403360208501613caa565b9150604084013590509250925092565b6000806040838503121561405657600080fd5b82359150602083013561406881613a80565b809150509250929050565b6000806040838503121561408657600080fd5b50508035926020909101359150565b6000602082840312156140a757600080fd5b813561171181613a80565b60018060a01b0385168152836020820152826040820152608060608201526000611ac86080830184613774565b600060208083850312156140f257600080fd5b82356001600160401b0381111561410857600080fd5b8301601f8101851361411957600080fd5b8035614127613da182613d2b565b81815260059190911b8201830190838101908783111561414657600080fd5b928401925b828410156141645783358252928401929084019061414b565b979650505050505050565b60008060006040848603121561418457600080fd5b83356001600160401b038082111561419b57600080fd5b6141a787838801613efe565b945060208601359150808211156141bd57600080fd5b50613b2086828701613a95565b634e487b7160e01b600052602160045260246000fd5b60208101600583106141f4576141f46141ca565b91905290565b60208152600060018060a01b03808451166020840152602084015115156040840152604084015160a0606085015261423560c0850182613774565b90508160608601515116608085015260808501519150601f198482030160a085015261201b81836137ba565b6000806020838503121561427457600080fd5b82356001600160401b0381111561428a57600080fd5b61429685828601613a95565b90969095509350505050565b600181811c908216806142b657607f821691505b602082108103613f1057634e487b7160e01b600052602260045260246000fd5b601f82111561144a57600081815260208120601f850160051c810160208610156142fd5750805b601f850160051c820191505b8181101561431c57828155600101614309565b505050505050565b81516001600160401b0381111561433d5761433d613919565b6143518161434b84546142a2565b846142d6565b602080601f831160018114614386576000841561436e5750858301515b600019600386901b1c1916600185901b17855561431c565b600085815260208120601f198616915b828110156143b557888601518255948401946001909101908401614396565b50858210156143d35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b808201808211156113da576113da6143e3565b60006113da3683613e01565b634e487b7160e01b600052603260045260246000fd5b600060018201614440576144406143e3565b5060010190565b818103818111156113da576113da6143e3565b6020808252825482820181905260008481528281209092916040850190845b81811015613b6e57835483526001938401939285019201614479565b60208101600283106141f4576141f46141ca565b80820281158282048414176113da576113da6143e3565b6000826144dd57634e487b7160e01b600052601260045260246000fd5b500490565b8381526001600160a01b038316602082015260606040820181905260009061201b90830184613774565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220fd21334ef3483ae8631dcf3ffb394cdffd811bdabfe2a857263421b3df8eb6f964736f6c63430008130033

Deployed Bytecode Sourcemap

122444:506:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67626:27;;;;;;;;;;;;;;;;;;;160:25:1;;;148:2;133:18;67626:27:0;;;;;;;;68462:49;;;;;;;;;;-1:-1:-1;68462:49:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;67791:27::-;;;;;;;;;;;;;;;;67597:22;;;;;;;;;;-1:-1:-1;67597:22:0;;;;-1:-1:-1;;;;;67597:22:0;;;;;;-1:-1:-1;;;;;2440:32:1;;;2422:51;;2410:2;2395:18;67597:22:0;2276:203:1;59440:24:0;;;;;;;;;;;;;;;;68337:35;;;;;;;;;;-1:-1:-1;68337:35:0;;;;;:::i;:::-;;:::i;67517:18::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;85416:60::-;;;;;;;;;;-1:-1:-1;85416:60:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;120541:125::-;;;;;;;;;;-1:-1:-1;120541:125:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;68574:32::-;;;;;;;;;;-1:-1:-1;68574:32:0;;;;;:::i;:::-;;:::i;72570:119::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;121011:595::-;;;;;;;;;;-1:-1:-1;121011:595:0;;;;;:::i;:::-;;:::i;74573:478::-;;;;;;;;;;-1:-1:-1;74573:478:0;;;;;:::i;:::-;;:::i;:::-;;73569:109;;;;;;;;;;;;;:::i;72374:127::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;59611:28::-;;;;;;;;;;-1:-1:-1;59611:28:0;;;;;:::i;:::-;;:::i;57116:551::-;;;;;;;;;;-1:-1:-1;57116:551:0;;;;;:::i;:::-;;:::i;:::-;;;9300:14:1;;9293:22;9275:41;;9263:2;9248:18;57116:551:0;9135:187:1;67260:73:0;;;;;;;;;;;;67313:20;67260:73;;59368:29;;;;;;;;;;;;;;;;67710:26;;;;;;;;;;;;;;;;68435:20;;;;;;;;;;-1:-1:-1;68435:20:0;;;;;;;;119576:34;;;;;;;;;;-1:-1:-1;119576:34:0;;;;;:::i;:::-;;:::i;119975:150::-;;;;;;;;;;-1:-1:-1;119975:150:0;;;;;:::i;:::-;;:::i;82135:539::-;;;;;;:::i;:::-;;:::i;71299:148::-;;;;;;;;;;-1:-1:-1;71299:148:0;;;;;:::i;:::-;;:::i;78163:612::-;;;;;;:::i;:::-;;:::i;67179:74::-;;;;;;;;;;;;;:::i;87445:591::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;68613:39::-;;;;;;;;;;-1:-1:-1;68613:39:0;;;;;:::i;:::-;;:::i;68268:25::-;;;;;;;;;;;;;;;;81687:376;;;;;;;;;;-1:-1:-1;81687:376:0;;;;;:::i;:::-;;:::i;84390:195::-;;;;;;;;;;-1:-1:-1;84390:195:0;;;;;:::i;:::-;;:::i;85902:297::-;;;;;;;;;;-1:-1:-1;85902:297:0;;;;;:::i;:::-;85966:16;86053:32;;;:20;:32;;;;;86104:40;;86146:44;;;;;86104:40;;85902:297;;;;;16336:25:1;;;16392:2;16377:18;;16370:34;;;;16309:18;85902:297:0;16162:248:1;71203:88:0;;;;;;;;;;-1:-1:-1;71276:7:0;;;;;;;;;;;;-1:-1:-1;;;71276:7:0;;;;71203:88;;89454:1049;;;;;;;;;;-1:-1:-1;89454:1049:0;;;;;:::i;:::-;;:::i;120360:117::-;;;;;;;;;;;;;:::i;68108:32::-;;;;;;;;;;;;;;;;82781:540;;;;;;:::i;:::-;;:::i;86307:418::-;;;;;;;;;;-1:-1:-1;86307:418:0;;;;;:::i;:::-;;:::i;68233:28::-;;;;;;;;;;;;;;;;60139:119;;;;;;;;;;;;;:::i;85485:58::-;;;;;;;;;;-1:-1:-1;85485:58:0;;;;;:::i;:::-;;:::i;68518:49::-;;;;;;;;;;-1:-1:-1;68518:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;118429:42;;;;;;;;;;-1:-1:-1;118429:42:0;;;;-1:-1:-1;;;;;118429:42:0;;;67570:20;;;;;;;;;;;;;:::i;85274:29::-;;;;;;;;;;;;;;;;67867:44;;;;;;;;;;;;;;;;119617:47;;;;;;;;;;-1:-1:-1;119617:47:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;90620:535::-;;;;;;;;;;-1:-1:-1;90620:535:0;;;;;:::i;:::-;;:::i;68720:57::-;;;;;;;;;;-1:-1:-1;68720:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;72184:113;;;;;;;;;;;;;:::i;68302:28::-;;;;;;;;;;-1:-1:-1;68302:28:0;;;;;:::i;:::-;;:::i;88480:172::-;;;;;;;;;;-1:-1:-1;88480:172:0;;;;;:::i;:::-;88573:13;88606:31;;;:21;:31;;;;;:38;;88480:172;85348:61;;;;;;;;;;-1:-1:-1;85348:61:0;;;;;:::i;:::-;;;;;;;;;;;;;;121711:726;;;;;;;;;;-1:-1:-1;121711:726:0;;;;;:::i;:::-;;:::i;119731:48::-;;;;;;;;;;-1:-1:-1;119731:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;87174:173;;;;;;;;;;-1:-1:-1;87174:173:0;;;;;:::i;:::-;-1:-1:-1;;;;;87300:39:0;87254:26;87300:39;;;:26;:39;;;;;;;87174:173;86831:227;;;;;;;;;;-1:-1:-1;86831:227:0;;;;;:::i;:::-;;:::i;88976:271::-;;;;;;;;;;-1:-1:-1;88976:271:0;;;;;:::i;:::-;;:::i;56052:35::-;;;;;;;;;;;;;;;;120759:142;;;;;;;;;;-1:-1:-1;120759:142:0;;;;;:::i;:::-;;:::i;77640:403::-;;;;;;:::i;:::-;;:::i;71455:495::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;73741:130::-;;;;;;;;;;-1:-1:-1;73741:130:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;88153:218::-;;;;;;;;;;-1:-1:-1;88153:218:0;;;;;:::i;:::-;;:::i;68784:56::-;;;;;;;;;;-1:-1:-1;68784:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;72769:444;;;;;;;;;;;;;:::i;84171:211::-;;;;;;;;;;-1:-1:-1;84171:211:0;;;;;:::i;:::-;;:::i;56094:31::-;;;;;;;;;;;;;;;;68661:52;;;;;;;;;;-1:-1:-1;68661:52:0;;;;;:::i;:::-;;;;;;;;;;;;;;73380:103;;;;;;;;;;;;;:::i;120187:::-;;;;;;;;;;;;;:::i;81232:332::-;;;;;;;;;;;;;:::i;68192:34::-;;;;;;;;;;;;;;;;67340:84;;;;;;;;;;;;67382:42;67340:84;;72011:105;;;;;;;;;;;;;:::i;79829:1284::-;;;;;;;;;;-1:-1:-1;79829:1284:0;;;;;:::i;:::-;;:::i;118646:384::-;;;;;;;;;;-1:-1:-1;118646:384:0;;;;;:::i;:::-;;:::i;119542:27::-;;;;;;;;;;-1:-1:-1;119542:27:0;;;;;:::i;:::-;;:::i;119671:53::-;;;;;;;;;;-1:-1:-1;119671:53:0;;;;;:::i;:::-;;:::i;68379:49::-;;;;;;;;;;-1:-1:-1;68379:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;75150:903;;;;;;;;;;-1:-1:-1;75150:903:0;;;;;:::i;:::-;;:::i;68018:31::-;;;;;;;;;;;;;;;;68462:49;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68462:49:0;;;-1:-1:-1;;;68462:49:0;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68462:49:0;;;;;;;;;;;;;-1:-1:-1;;;;;68462:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68462:49:0;;-1:-1:-1;68462:49:0;-1:-1:-1;68462:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68462:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;68337:35::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68337:35:0;:::o;67517:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;120541:125::-;120601:18;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120601:18:0;120639:19;;;;:8;:19;;;;;;;;;120632:26;;;;;;;;;-1:-1:-1;;;;;120632:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120639:19;120632:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120541:125;;;:::o;68574:32::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68574:32:0;;-1:-1:-1;68574:32:0;:::o;72570:119::-;72627:16;72663:18;72656:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72570:119;:::o;121011:595::-;121149:180;;;;;;;;121184:10;121149:180;;121220:15;121149:180;;;;;;;;;;;;;;;;121094:7;;;121360:26;121149:180;121360:11;:26::i;:::-;121399:10;:26;;;;;;;;;;;;;;-1:-1:-1;121436:19:0;;;:8;121399:26;121436:19;;;;;;;;:35;;;;-1:-1:-1;;;;;;121436:35:0;-1:-1:-1;;;;;121436:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;121399:26;;-1:-1:-1;121436:35:0;;;;;;;;;;:::i;:::-;-1:-1:-1;;;121482:28:0;;;;:16;:28;;;;;;;;:44;;;;;;;;;;;;;;;;;;121544:25;;;;;121516:9;160:25:1;;148:2;133:18;;14:177;121544:25:0;;;;;;;;121589:9;-1:-1:-1;;121011:595:0;;;;;:::o;74573:478::-;-1:-1:-1;;;;;74663:33:0;;;;;;:24;:33;;;;;;;;74658:386;;74717:20;;74741:1;74717:25;74713:144;;74573:478;;;:::o;74713:144::-;74871:61;74882:7;67313:20;74919:5;;74926;74871:10;:61::i;:::-;-1:-1:-1;;;;;;74992:33:0;;;;;;:24;:33;;;;;:40;;-1:-1:-1;;74992:40:0;75028:4;74992:40;;;74658:386;74573:478;;;:::o;73569:109::-;73617:7;73658:12;;73644:11;:9;:11::i;:::-;:26;;;;:::i;:::-;73637:33;;73569:109;:::o;72374:127::-;72435:16;72471:22;72464:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;72464:29:0;;;;;;;;;;;;;;;;;;;;;;72374:127;:::o;59611:28::-;;;;;;;;;;;;57116:551;57377:40;;-1:-1:-1;;24999:2:1;24995:15;;;24991:53;57377:40:0;;;24979:66:1;25061:12;;;25054:28;;;57263:13:0;;;;25098:12:1;;57377:40:0;;;;;;;;;;;;57367:51;;;;;;57352:66;;57429:16;57448:6;:140;;57535:53;57554:5;;57535:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57561:20:0;;;-1:-1:-1;57583:4:0;;-1:-1:-1;57535:18:0;:53::i;:::-;57448:140;;;57470:49;57489:5;;57470:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;57496:16:0;;;-1:-1:-1;57514:4:0;;-1:-1:-1;57470:18:0;:49::i;:::-;57429:159;;57604:11;57599:38;;57624:13;;-1:-1:-1;;;57624:13:0;;;;;;;;;;;57599:38;-1:-1:-1;57655:4:0;;57116:551;-1:-1:-1;;;;;;;57116:551:0:o;119576:34::-;;;;;;;;;;;;119975:150;120048:7;120104:10;120093:22;;;;;;;;:::i;:::-;;;;-1:-1:-1;;120093:22:0;;;;;;;;;120083:33;;120093:22;120083:33;;;;;119975:150;-1:-1:-1;;119975:150:0:o;82135:539::-;82303:7;82328:18;82349:41;82377:12;82349:27;:41::i;:::-;82403:13;82444:29;;;:17;:29;;;;;;82328:62;;-1:-1:-1;82419:10:0;;82444:29;;82440:71;;;82482:29;;-1:-1:-1;;;82482:29:0;;;;;;;;;;;82440:71;82522:37;82534:5;82541:10;82553:5;;82522:11;:37::i;:::-;82572:27;82588:10;82572:15;:27::i;:::-;82619:47;82629:10;82641:5;82648:7;82657:8;82619:9;:47::i;:::-;82612:54;82135:539;-1:-1:-1;;;;;;;;;82135:539:0:o;71299:148::-;71372:7;71428:8;71417:20;;;;;;;;:::i;78163:612::-;78248:7;78268:18;78289:43;78317:14;78289:27;:43::i;:::-;78349:20;;78268:64;;-1:-1:-1;78349:25:0;78345:257;;78542:10;78517:36;;;;:24;:36;;;;;;;;78512:78;;78562:28;;-1:-1:-1;;;78562:28:0;;;;;;;;;;;78512:78;78612:30;;78633:8;78612:30;:::i;:::-;78653:18;78674:23;;78688:8;78674:23;:::i;:::-;:13;:23::i;:::-;78653:44;;78710:27;78726:10;78710:15;:27::i;:::-;78757:10;78163:612;-1:-1:-1;;;78163:612:0:o;67179:74::-;67221:32;67229:19;;67221:32;:::i;:::-;67179:74;:::o;87445:591::-;87526:34;87562:49;87629:34;87666:19;:17;:19::i;:::-;87629:56;;87696:43;87759:17;:24;-1:-1:-1;;;;;87742:42:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;87742:42:0;;;;;;;;;;;;;;;;87696:88;;87800:9;87795:172;87819:17;:24;87815:1;:28;87795:172;;;87894:20;:42;87915:17;87933:1;87915:20;;;;;;;;:::i;:::-;;;;;;;87894:42;;;;;;;;;;;:61;;87865:90;;;;;;;;;;;;;;;;;;;;;;;;;:23;87889:1;87865:26;;;;;;;;:::i;:::-;;;;;;:90;;;;87845:3;;;;;:::i;:::-;;;;87795:172;;;-1:-1:-1;87985:17:0;;88004:23;;-1:-1:-1;87445:591:0;-1:-1:-1;87445:591:0:o;68613:39::-;;;;;;;;;;;;81687:376;-1:-1:-1;;;;;81794:34:0;;;;;;:25;:34;;;;;;;;81789:267;;81845:44;81856:7;81865:10;81877:5;;81884:4;81845:10;:44::i;:::-;-1:-1:-1;;;;;;81949:26:0;;;;;;:17;:26;;;;;;;;:39;;;82003:25;:34;;;;;:41;;-1:-1:-1;;82003:41:0;82040:4;82003:41;;;81789:267;81687:376;;;;:::o;84390:195::-;84470:10;67382:42;84470:29;84466:62;;84508:20;;-1:-1:-1;;;84508:20:0;;;;;;;;;;;84466:62;84539:16;:38;84390:195::o;89454:1049::-;89511:17;89545:4;89553:1;89545:9;89541:40;;89563:18;;-1:-1:-1;;;89563:18:0;;;;;;;;;;;89541:40;89622:11;:18;;89695:48;;;;;;;;;;;;;;;;;89622:18;;89594:25;;89695:48;89622:18;;89695:48;;89622:11;:18;89695:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89800:15;89818:1;89800:19;;89835:13;89830:547;89862:17;89854:5;:25;89830:547;;;90063:61;90099:17;90117:5;90099:24;;;;;;;;:::i;:::-;;;;;;;88573:13;88606:31;;;:21;:31;;;;;:38;;88480:172;90063:61;90059:115;90150:8;90059:115;90289:4;90278:7;:15;90274:68;;90321:5;89454:1049;-1:-1:-1;;;;;89454:1049:0:o;90274:68::-;90356:9;;;;:::i;:::-;;;;89830:547;89881:7;;;;:::i;:::-;;;;89830:547;;;;90471:24;;-1:-1:-1;;;90471:24:0;;;;;;;;;;;120360:117;120416:16;120452:17;120445:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120360:117;:::o;82781:540::-;82915:7;82940:18;82961:41;82989:12;82961:27;:41::i;:::-;83015:13;83056:29;;;:17;:29;;;;;;82940:62;;-1:-1:-1;83031:10:0;;83056:29;;83052:71;;;83094:29;;-1:-1:-1;;;83094:29:0;;;;;;;;;;;83052:71;-1:-1:-1;;;;;83139:32:0;;;;;;:25;:32;;;;;;;;83134:72;;83180:26;;-1:-1:-1;;;83180:26:0;;;;;;;;;;;83134:72;83219:27;83235:10;83219:15;:27::i;:::-;83266:47;83276:10;83288:5;83295:7;83304:8;83266:9;:47::i;:::-;83259:54;82781:540;-1:-1:-1;;;;;;82781:540:0:o;86307:418::-;86426:16;86518:32;;;:20;:32;;;;;;;;-1:-1:-1;;;;;86583:43:0;;;;:30;;:43;;;;;:52;;86650:56;;;;;86307:418;;;;;;:::o;60139:119::-;60186:33;60239:11;60232:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60139:119;:::o;85485:58::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;67570:20::-;;;;;;;:::i;119617:47::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;119617:47:0;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;90620:535::-;90728:11;:18;90683:22;;90728;;90749:1;;90728:22;:::i;:::-;90722:3;:28;90718:208;;;90888:26;;-1:-1:-1;;;90888:26:0;;;;;;;;;;;90718:208;90943:13;90938:187;90970:7;:3;90976:1;90970:7;:::i;:::-;90962:5;:15;90938:187;;;91065:1;91007:55;91043:11;91055:5;91043:18;;;;;;;;:::i;:::-;;;;;;;;;88573:13;88606:31;;;:21;:31;;;;;:38;;88480:172;91007:55;:59;91003:111;;;-1:-1:-1;91094:4:0;;90620:535;-1:-1:-1;;90620:535:0:o;91003:111::-;90979:7;;;;:::i;:::-;;;;90938:187;;;-1:-1:-1;91142:5:0;;90620:535;-1:-1:-1;;90620:535:0:o;72184:113::-;72238:16;72274:15;72267:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;72267:22:0;;;;;;;;;;;;;;;;;;;;;;72184:113;:::o;68302:28::-;;;;;;;;;;;;121711:726;121819:22;;121787:29;121854:526;121886:21;121878:5;:29;121854:526;;;121933:24;121960:15;121976:5;121960:22;;;;;;;;:::i;:::-;;;;;;;;;;;122018:7;;121960:22;;-1:-1:-1;;;;;;122018:7:0;122004:10;:21;;;;122003:76;;-1:-1:-1;122045:26:0;;;;:8;:26;;;;;:33;-1:-1:-1;;;;;122045:33:0;122031:10;:47;;122003:76;121999:178;;;122107:54;;-1:-1:-1;;;122107:54:0;;;;;160:25:1;;;133:18;;122107:54:0;;;;;;;;121999:178;122198:34;;;;:16;:34;;;;;;;;122193:176;;122253:34;;;;:16;:34;;;;;:41;;-1:-1:-1;;122253:41:0;122290:4;122253:41;;;;;;122313:17;:40;;;;;;;;;;;;;;;122193:176;-1:-1:-1;121909:7:0;;;;:::i;:::-;;;;121854:526;;;;122397:32;122413:15;122397:32;;;;;;:::i;:::-;;;;;;;;121776:661;121711:726;:::o;86831:227::-;86937:33;86973:32;;;:20;:32;;;;;;;;;87023:27;;;87016:34;;;;;;;;;;;;;;;;;86908:16;;86973:32;;87016:34;;87023:27;87016:34;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;87016:34:0;;;;;;;;;;;;;;;;;;;;;;;;86831:227;;;:::o;88976:271::-;89062:18;89097:31;;;:21;:31;;;;;:38;89139:1;89097:43;89093:94;;89149:38;;-1:-1:-1;;;89149:38:0;;;;;;;;;;;89093:94;89205:31;;;;:21;:31;;;;;:34;;:31;;;:34;;;;:::i;:::-;;;;;;;;;89198:41;;88976:271;;;:::o;120759:142::-;120865:28;;;;:16;:28;;;;;;;;;120858:35;;;;;;;;;;;;;;;;;120829:16;;120858:35;;;120865:28;120858:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120759:142;;;:::o;77640:403::-;77739:7;77759:18;77780:43;77808:14;77780:27;:43::i;:::-;77759:64;;77836:33;77851:10;77863:5;;77836:14;:33::i;:::-;77880:30;;77901:8;77880:30;:::i;:::-;77921:18;77942:23;;77956:8;77942:23;:::i;:::-;77921:44;;77978:27;77994:10;77978:15;:27::i;:::-;78025:10;77640:403;-1:-1:-1;;;;;77640:403:0:o;71455:495::-;71522:8;;71493:12;;71522:8;;71518:69;;;-1:-1:-1;71554:21:0;;71455:495::o;71518:69::-;71619:15;71603:12;;:31;71599:94;;-1:-1:-1;71658:23:0;;71455:495::o;71599:94::-;71724:15;71709:11;:9;:11::i;:::-;:30;71705:89;;-1:-1:-1;71763:19:0;;71455:495::o;71705:89::-;71831:15;71810:17;:15;:17::i;:::-;:36;71806:95;;-1:-1:-1;71870:19:0;;71455:495::o;71806:95::-;-1:-1:-1;71920:22:0;;71455:495::o;73741:130::-;73803:19;;:::i;:::-;73842:21;;;;:9;:21;;;;;;;;;73835:28;;;;;;;;;-1:-1:-1;;;;;73835:28:0;;;;-1:-1:-1;;;73835:28:0;;;;;;;;;;;;;;;;;;;;73842:21;;73835:28;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;73835:28:0;;;-1:-1:-1;;73835:28:0;;;;;;;;;;;;;-1:-1:-1;;;;;73835:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;73835:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73741:130;;;:::o;88153:218::-;88332:31;;;;:21;:31;;;;;;;;;88325:38;;;;;;;;;;;;;;;;;88261:46;;88325:38;;;88332:31;88325:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88153:218;;;:::o;72769:444::-;72833:16;72862:41;72906:18;72862:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72935:29;72981:24;:31;-1:-1:-1;;;;;72967:46:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72967:46:0;;72935:78;;73029:9;73024:152;73048:24;:31;73044:1;:35;73024:152;;;73119:9;:38;73129:24;73154:1;73129:27;;;;;;;;:::i;:::-;;;;;;;73119:38;;;;;;;;;;;:45;;;;;;;;;;-1:-1:-1;;;;;73119:45:0;73101:12;73114:1;73101:15;;;;;;;;:::i;:::-;-1:-1:-1;;;;;73101:63:0;;;:15;;;;;;;;;;;:63;73081:3;;;;:::i;:::-;;;;73024:152;;;-1:-1:-1;73193:12:0;72769:444;-1:-1:-1;;72769:444:0:o;84171:211::-;84259:10;67382:42;84259:29;84255:62;;84297:20;;-1:-1:-1;;;84297:20:0;;;;;;;;;;;84255:62;84328:20;:46;84171:211::o;73380:103::-;73422:7;73464:11;;73449:12;;:26;;;;:::i;120187:103::-;120236:16;120272:10;120265:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120187:103;:::o;81232:332::-;81288:7;;-1:-1:-1;;;;;81288:7:0;81274:10;:21;;;;81273:58;;-1:-1:-1;81301:10:0;67382:42;81301:29;;81273:58;81268:103;;;81341:30;;-1:-1:-1;;;81341:30:0;;;;;;;;;;;81268:103;81384:19;81406:7;:5;:7::i;:::-;81384:29;-1:-1:-1;81438:21:0;81428:6;:31;;;;;;;;:::i;:::-;;81424:69;;81468:25;;-1:-1:-1;;;81468:25:0;;;;;;;;;;;81424:69;81506:8;:15;;-1:-1:-1;;81506:15:0;81517:4;81506:15;;;81539:17;;;;81506:8;;81539:17;81257:307;81232:332::o;72011:105::-;72061:16;72097:11;72090:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72011:105;:::o;79829:1284::-;79930:7;;-1:-1:-1;;;;;79930:7:0;79916:10;:21;79912:56;;79946:22;;-1:-1:-1;;;79946:22:0;;;;;;;;;;;79912:56;79994:22;79983:7;:5;:7::i;:::-;:33;;;;;;;;:::i;:::-;;79979:73;;80025:27;;-1:-1:-1;;;80025:27:0;;;;;;;;;;;79979:73;80070:13;80065:629;80089:34;;;80065:629;;;80149:25;80177:19;;80197:5;80177:26;;;;;;;:::i;:::-;;;;;;;;;;80223:36;;;;:17;:36;;;;;;;;80177:26;;-1:-1:-1;;80223:36:0;;80218:465;;80345:36;;;;:17;:36;;;;;:43;;-1:-1:-1;;80345:43:0;80384:4;80345:43;;;;;;80625:18;:42;;;;;;;;;;;;;;;80218:465;-1:-1:-1;80125:7:0;;;;:::i;:::-;;;;80065:629;;;-1:-1:-1;80793:17:0;;:22;:45;;;;;80819:14;;80837:1;80819:19;80793:45;80789:270;;;80993:54;81027:19;;80993:33;:54::i;:::-;81076:29;81093:11;81076:29;;;;;;:::i;118646:384::-;118754:7;;-1:-1:-1;;;;;118754:7:0;118740:10;:21;118736:66;;118770:32;;-1:-1:-1;;;118770:32:0;;;;;;;;;;;118736:66;118854:21;;;-1:-1:-1;;;;;118886:46:0;;;-1:-1:-1;;;;;;118886:46:0;;;;;;118948:74;;;118854:21;;;;26671:34:1;;;26721:18;;;26714:43;118948:74:0;;26606:18:1;118948:74:0;26399:364:1;119542:27:0;;;;;;;;;;;;119671:53;;;;;;;;;;;;;;;;;;;;75150:903;75237:15;;-1:-1:-1;;;;;75237:29:0;75256:10;75237:29;75233:88;;75293:15;;75275:46;;-1:-1:-1;;;75275:46:0;;-1:-1:-1;;;;;26689:15:1;;;75275:46:0;;;26671:34:1;75310:10:0;26721:18:1;;;26714:43;26606:18;;75275:46:0;26399:364:1;75233:88:0;75337:13;75332:625;67221:32;67229:19;;67221:32;:::i;:::-;75356:5;:23;75332:625;;;75405:25;75443:5;75433:16;;;;;;;;:::i;:::-;75405:44;-1:-1:-1;75487:16:0;75468:15;:35;;;;;;;;:::i;:::-;;75464:482;;75524:8;;;75464:482;75634:14;75615:15;:33;;;;;;;;:::i;:::-;;75611:335;;75673:21;;;;:29;:36;:29;:41;75669:81;;75723:27;;-1:-1:-1;;;75723:27:0;;;;;;;;;;;75669:81;75773:8;:21;;;:31;;;75808:1;75773:36;75769:78;;75818:29;;-1:-1:-1;;;75818:29:0;;;;;;;;;;;75769:78;75611:335;;;75914:15;75895:35;;-1:-1:-1;;;75895:35:0;;;;;;;;:::i;75611:335::-;75390:567;75332:625;75381:7;;;;:::i;:::-;;;;75332:625;;;;75977:8;:20;;;75971:34;76009:1;75971:39;75967:78;;76019:26;;-1:-1:-1;;;76019:26:0;;;;;;;;;;;75967:78;75150:903;:::o;47185:156::-;47276:4;47329;47300:25;47313:5;47320:4;47300:12;:25::i;:::-;:33;;47185:156;-1:-1:-1;;;;47185:156:0:o;76190:479::-;76268:7;;;76321:13;:31;;;;;;;;:::i;:::-;;76317:228;;-1:-1:-1;76382:13:0;;76317:228;;;76434:12;76417:13;:29;;;;;;;;:::i;:::-;;76413:132;;-1:-1:-1;76476:10:0;;76413:132;;;-1:-1:-1;76532:1:0;76413:132;76574:10;76561:9;:23;76557:76;;76593:40;;-1:-1:-1;;;76593:40:0;;76611:9;76593:40;;;16336:25:1;16377:18;;;16370:34;;;16309:18;;76593:40:0;16162:248:1;76795:783:0;76864:14;;76860:711;;76960:23;77030:3;77006:19;;77000:3;:25;;;;:::i;:::-;76987:39;;:9;:39;:::i;:::-;76986:47;;;;:::i;:::-;76960:73;-1:-1:-1;77052:19:0;;77048:193;;77092:60;67382:42;77136:15;77092:17;:60::i;:::-;77176:49;;;67382:42;27896:51:1;;27978:2;27963:18;;27956:34;;;77176:49:0;;27869:18:1;77176:49:0;;;;;;;77048:193;77257:24;77284:27;77296:15;77284:9;:27;:::i;:::-;77257:54;-1:-1:-1;77330:20:0;;77326:234;;77397:7;;77371:53;;-1:-1:-1;;;;;77397:7:0;77407:16;77371:17;:53::i;:::-;77518:7;;77502:42;;;-1:-1:-1;;;;;77518:7:0;;;27896:51:1;;27978:2;27963:18;;27956:34;;;77502:42:0;;27869:18:1;77502:42:0;;;;;;;76880:691;;76795:783;:::o;83610:553::-;83735:7;83775:19;83764:7;:5;:7::i;:::-;:30;;;;;;;;:::i;:::-;;83760:77;;83829:7;:5;:7::i;:::-;83803:34;;-1:-1:-1;;;83803:34:0;;;;;;;;:::i;83760:77::-;83852:8;83864:1;83852:13;83848:52;;83874:26;;-1:-1:-1;;;83874:26:0;;;;;;;;;;;83848:52;83913:78;83924:10;83936:7;83945;83954:8;83964:17;:26;83982:7;-1:-1:-1;;;;;83964:26:0;-1:-1:-1;;;;;83964:26:0;;;;;;;;;;;;;83913:10;:78::i;:::-;84004:22;:39;;;;;;;-1:-1:-1;84004:39:0;;;;;;;;-1:-1:-1;;;;;;84004:39:0;84032:10;84004:39;;;84061:48;;;28199:25:1;;;28272:4;28260:17;;28255:2;28240:18;;28233:45;28294:18;;;28287:34;;;-1:-1:-1;;;;;84061:48:0;;;;;28187:2:1;28172:18;84061:48:0;;;;;;;-1:-1:-1;;;;;;;;84129:26:0;;;;;:17;:26;;;;;;;83610:553;-1:-1:-1;83610:553:0:o;78783:929::-;78854:7;78889:19;78878:7;:5;:7::i;:::-;:30;;;;;;;;:::i;:::-;;78874:80;;78946:7;:5;:7::i;:::-;78917:37;;-1:-1:-1;;;78917:37:0;;;;;;;;:::i;78874:80::-;78999:29;;78984:10;78969:26;;;;:14;:26;;;;;;:59;78965:158;;79081:29;;79052:59;;-1:-1:-1;;;79052:59:0;;;;;;160:25:1;;148:2;133:18;;14:177;78965:158:0;79189:16;;79159:18;:25;79138:11;:18;:46;;79159:25;79138:46;:::i;:::-;79137:68;79133:155;;79259:16;;79229:47;;-1:-1:-1;;;79229:47:0;;;;;;160:25:1;;148:2;133:18;;14:177;79133:155:0;79300:18;79321:22;79334:8;79321:12;:22::i;:::-;79358:21;;;;:9;:21;;;;;:28;:21;;-1:-1:-1;;;;79358:28:0;;;;79354:72;;;79395:31;;-1:-1:-1;;;79395:31:0;;;;;160:25:1;;;133:18;;79395:31:0;14:177:1;79354:72:0;79439:11;:28;;;;;;;;;;;;;;-1:-1:-1;79478:21:0;;;:9;79439:28;79478:21;;;;;;;;:32;;;;;;;;;;-1:-1:-1;;;79478:32:0;-1:-1:-1;;;;;;79478:32:0;;;-1:-1:-1;;;;;79478:32:0;;;;;;;;;;;;;;79502:8;;79478:32;;;;;;;:::i;:::-;-1:-1:-1;79478:32:0;;;;;;;;;;-1:-1:-1;;;;;;79478:32:0;-1:-1:-1;;;;;79478:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;79478:32:0;;;;;;;;;;79536:10;79521:26;;;;:14;:26;;;;;;:31;;79478:32;;-1:-1:-1;79521:26:0;-1:-1:-1;79521:31:0;;79478:32;;79521:31;:::i;:::-;;;;-1:-1:-1;;79563:15:0;:32;;;;;;;-1:-1:-1;79563:32:0;;;;;;;;-1:-1:-1;;;;;;79563:32:0;79584:10;79563:32;;;;;;79653:20;;;;;79613:61;;;;;;79629:10;;79613:61;:::i;:::-;;;;;;;;79694:10;78783:929;-1:-1:-1;;78783:929:0:o;92276:615::-;92393:9;92388:496;92408:30;;;92388:496;;;92460:25;92488:19;;92508:1;92488:22;;;;;;;:::i;:::-;;;;;;;;;;92525:32;92560:39;;;:20;:39;;;;;;;:67;92488:22;;-1:-1:-1;92799:73:0;;-1:-1:-1;92488:22:0;92560:67;92799:28;:73::i;:::-;92445:439;;92440:3;;;;;:::i;:::-;;;;92388:496;;47984:296;48067:7;48110:4;48067:7;48125:118;48149:5;:12;48145:1;:16;48125:118;;;48198:33;48208:12;48222:5;48228:1;48222:8;;;;;;;;:::i;:::-;;;;;;;48198:9;:33::i;:::-;48183:48;-1:-1:-1;48163:3:0;;;;:::i;:::-;;;;48125:118;;;-1:-1:-1;48260:12:0;47984:296;-1:-1:-1;;;47984:296:0:o;38999:317::-;39114:6;39089:21;:31;;39081:73;;;;-1:-1:-1;;;39081:73:0;;28927:2:1;39081:73:0;;;28909:21:1;28966:2;28946:18;;;28939:30;29005:31;28985:18;;;28978:59;29054:18;;39081:73:0;28725:353:1;39081:73:0;39168:12;39186:9;-1:-1:-1;;;;;39186:14:0;39208:6;39186:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39167:52;;;39238:7;39230:78;;;;-1:-1:-1;;;39230:78:0;;29495:2:1;39230:78:0;;;29477:21:1;29534:2;29514:18;;;29507:30;29573:34;29553:18;;;29546:62;29644:28;29624:18;;;29617:56;29690:19;;39230:78:0;29293:422:1;93036:2120:0;93198:33;93234:32;;;:20;:32;;;;;;;;-1:-1:-1;;;;;93308:35:0;;;;:26;:35;;;;;;;93295:48;;:10;:48;:::i;:::-;93283:8;:61;93279:94;;;93353:20;;-1:-1:-1;;;93353:20:0;;;;;;;;;;;93279:94;-1:-1:-1;;;;;93424:39:0;;93386:20;93424:39;;;:30;;;:39;;;;;:48;:53;:131;;;;-1:-1:-1;;;;;;93498:39:0;;;;;;:30;;;:39;;;;;:52;;;:57;93424:131;93386:180;-1:-1:-1;93583:30:0;;;93579:527;;93630:52;;93674:8;;93630:12;;:31;;:52;;93674:8;;93630:52;:::i;:::-;;;;-1:-1:-1;;;;;;;93697:39:0;;;;;;:30;;;:39;;;;;:60;;93749:8;;93697:39;:60;;93749:8;;93697:60;:::i;:::-;;;;-1:-1:-1;93579:527:0;;-1:-1:-1;93579:527:0;;-1:-1:-1;;93779:34:0;;;;93775:331;;93834:17;;93855:1;93834:22;93830:57;;93865:22;;-1:-1:-1;;;93865:22:0;;;;;;;;;;;93830:57;93950:8;93902:12;:31;;:44;;;:56;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;93973:39:0;;;;;;:30;;;:39;;;;;:52;;:64;;94029:8;;93973:39;:64;;94029:8;;93973:64;:::i;93775:331::-;94077:17;;-1:-1:-1;;;94077:17:0;;;;;;;;;;;93775:331;94122:15;94118:89;;;94154:27;;;:41;;;;;;;-1:-1:-1;94154:41:0;;;;;;;;;;-1:-1:-1;;;;;;94154:41:0;-1:-1:-1;;;;;94154:41:0;;;;;94118:89;-1:-1:-1;;;;;94217:35:0;;;;;;:26;:35;;;;;:47;;94256:8;;94217:35;:47;;94256:8;;94217:47;:::i;:::-;;;;;;;;94293:8;94275:14;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;;94449:17:0;;:22;94448:49;;;;;94477:14;;94495:1;94477:19;94448:49;94444:705;;;94536:40;;94514:19;94657:22;94671:8;94536:40;94657:22;:::i;:::-;94635:44;-1:-1:-1;94912:15:0;;94908:109;;94948:53;94977:10;94989:11;94948:28;:53::i;:::-;95031:34;;;;:21;:34;;;;;;;:51;;;;;;;;;;;;;;;;95099:38;95112:11;95053;95099:12;:38::i;:::-;94499:650;;94444:705;93187:1969;;93036:2120;;;;;:::o;91323:864::-;91419:39;91461:31;;;:21;:31;;;;;;;;91419:73;;;;;;;;;;;;;;;;;;;91461:31;;91419:73;;;91461:31;91419:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91552:9;91547:633;91571:22;:29;91567:1;:33;91547:633;;;91655:10;91626:22;91649:1;91626:25;;;;;;;;:::i;:::-;;;;;;;:39;91622:547;;92016:22;92071:1;92039:22;:29;:33;;;;:::i;:::-;92016:57;;;;;;;;:::i;:::-;;;;;;;91979:21;:31;92001:8;91979:31;;;;;;;;;;;92011:1;91979:34;;;;;;;;:::i;:::-;;;;;;;;:94;;;;92092:21;:31;92114:8;92092:31;;;;;;;;;;;:37;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;92148:5;;91622:547;91602:3;;;;:::i;:::-;;;;91547:633;;55422:149;55485:7;55516:1;55512;:5;:51;;55647:13;55741:15;;;55777:4;55770:15;;;55824:4;55808:21;;55512:51;;;-1:-1:-1;55647:13:0;55741:15;;;55777:4;55770:15;55824:4;55808:21;;;55422:149::o;64035:1363::-;64141:11;:18;;64214:48;;;;;;;;;;;;;;;;;64141:18;;64113:25;;64214:48;64141:18;;64214:48;;64141:11;:18;64214:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64432:17;64453:1;64432:22;64428:102;;-1:-1:-1;;64471:11:0;:26;;;;;;;-1:-1:-1;64471:26:0;;;;;;;-1:-1:-1;64035:1363:0:o;64428:102::-;64789:17;64807:21;64827:1;64807:17;:21;:::i;:::-;64789:40;;;;;;;;:::i;:::-;;;;;;;64778:8;:51;64774:433;;;64871:9;;64850:17;:30;64846:350;;64990:7;;64035:1363;;:::o;64846:350::-;-1:-1:-1;;65129:11:0;:26;;;;;;;-1:-1:-1;65129:26:0;;;;;;;-1:-1:-1;64035:1363:0:o;64846:350::-;65321:69;65333:8;65343;65353:17;65372;60711:22;;60744:505;60776:17;60768:5;:25;60744:505;;;60925:17;60943:5;60925:24;;;;;;;;:::i;:::-;;;;;;;60913:8;:36;60909:191;;61078:7;;;;60909:191;61131:17;61149:5;61131:24;;;;;;;;:::i;:::-;;;;;;;61120:8;:35;61116:122;;;61193:5;61176:22;;61217:5;;61116:122;60795:7;;;;:::i;:::-;;;;60744:505;;;;61307:21;61343:1;61332:8;:12;61331:70;;;;-1:-1:-1;88573:13:0;88606:31;;;:21;:31;;;;;:38;61350:50;61331:70;61307:94;;61487:22;61754:16;:67;;;;;61812:8;61775:17;61793:14;61775:33;;;;;;;;:::i;:::-;;;;;;;:45;61754:67;61748:1679;;62195:21;62215:1;62195:17;:21;:::i;:::-;62177:14;:39;62171:856;;62493:13;62509:18;:14;62526:1;62509:18;:::i;:::-;62493:34;;62488:524;62537:17;62529:5;:25;62488:524;;;62609:17;62627:9;62635:1;62627:5;:9;:::i;:::-;62609:28;;;;;;;;:::i;:::-;;;;;;;62588:11;62600:5;62588:18;;;;;;;;:::i;:::-;;;;;;;;;;:49;62826:16;:58;;;;;62875:8;62847:17;62865:5;62847:24;;;;;;;;:::i;:::-;;;;;;;:36;62826:58;62822:171;;;62933:4;62913:24;;62964:5;;62822:171;62556:7;;;;:::i;:::-;;;;62488:524;;;;62171:856;63269:17;63268:18;:53;;;;;63311:9;;63291:17;:29;63268:53;63264:152;;;63342:11;63359:17;63377:21;63397:1;63377:17;:21;:::i;:::-;63359:40;;;;;;;;:::i;:::-;;;;;;;;;;;;63342:58;;;;;;;-1:-1:-1;63342:58:0;;;;;;;;;63264:152;63591:8;63561:11;63573:14;63561:27;;;;;;;;:::i;:::-;;;;;;;;;;:38;-1:-1:-1;;;60479:3128:0;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;196:180:1;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;381:423::-;423:3;461:5;455:12;488:6;483:3;476:19;513:1;523:162;537:6;534:1;531:13;523:162;;;599:4;655:13;;;651:22;;645:29;627:11;;;623:20;;616:59;552:12;523:162;;;527:3;730:1;723:4;714:6;709:3;705:16;701:27;694:38;793:4;786:2;782:7;777:2;769:6;765:15;761:29;756:3;752:39;748:50;741:57;;;381:423;;;;:::o;809:668::-;937:12;;903:4;958:17;;;1024:19;;894:14;;;1052:20;;;864:3;;1121:4;;1148:21;;;;1099:2;1090:12;;;864:3;1197:201;1211:6;1208:1;1205:13;1197:201;;;1278:13;;-1:-1:-1;;;;;1274:39:1;1260:54;;1373:15;;;;1336:14;;;;1310:1;1226:9;1197:201;;;-1:-1:-1;;1434:14:1;;;1428:21;1414:12;;;;1407:43;;;;-1:-1:-1;1466:5:1;809:668;-1:-1:-1;809:668:1:o;1482:789::-;1824:4;1870:1;1866;1861:3;1857:11;1853:19;1911:2;1903:6;1899:15;1888:9;1881:34;1965:6;1958:14;1951:22;1946:2;1935:9;1931:18;1924:50;2010:3;2005:2;1994:9;1990:18;1983:31;2037:46;2078:3;2067:9;2063:19;2055:6;2037:46;:::i;:::-;2138:2;2129:6;2123:13;2119:22;2114:2;2103:9;2099:18;2092:50;2191:9;2183:6;2179:22;2173:3;2162:9;2158:19;2151:51;2219:46;2258:6;2250;2219:46;:::i;2484:220::-;2633:2;2622:9;2615:21;2596:4;2653:45;2694:2;2683:9;2679:18;2671:6;2653:45;:::i;2865:255::-;2785:12;;2773:25;;2847:4;2836:16;;;2830:23;2814:14;;;2807:47;3055:2;3040:18;;3067:47;2709:151;3125:553;3312:2;3301:9;3294:21;3387:1;3383;3378:3;3374:11;3370:19;3361:6;3355:13;3351:39;3346:2;3335:9;3331:18;3324:67;3445:2;3437:6;3433:15;3427:22;3422:2;3411:9;3407:18;3400:50;3504:2;3496:6;3492:15;3486:22;3481:2;3470:9;3466:18;3459:50;3275:4;3556:2;3548:6;3544:15;3538:22;3598:4;3591;3580:9;3576:20;3569:34;3620:52;3667:3;3656:9;3652:19;3638:12;3620:52;:::i;:::-;3612:60;3125:553;-1:-1:-1;;;;3125:553:1:o;3683:435::-;3736:3;3774:5;3768:12;3801:6;3796:3;3789:19;3827:4;3856:2;3851:3;3847:12;3840:19;;3893:2;3886:5;3882:14;3914:1;3924:169;3938:6;3935:1;3932:13;3924:169;;;3999:13;;3987:26;;4033:12;;;;4068:15;;;;3960:1;3953:9;3924:169;;;-1:-1:-1;4109:3:1;;3683:435;-1:-1:-1;;;;;3683:435:1:o;4123:261::-;4302:2;4291:9;4284:21;4265:4;4322:56;4374:2;4363:9;4359:18;4351:6;4322:56;:::i;4389:127::-;4450:10;4445:3;4441:20;4438:1;4431:31;4481:4;4478:1;4471:15;4505:4;4502:1;4495:15;4521:257;4593:4;4587:11;;;4625:17;;-1:-1:-1;;;;;4657:34:1;;4693:22;;;4654:62;4651:88;;;4719:18;;:::i;:::-;4755:4;4748:24;4521:257;:::o;4783:253::-;4855:2;4849:9;4897:4;4885:17;;-1:-1:-1;;;;;4917:34:1;;4953:22;;;4914:62;4911:88;;;4979:18;;:::i;5041:251::-;5113:2;5107:9;5155:2;5143:15;;-1:-1:-1;;;;;5173:34:1;;5209:22;;;5170:62;5167:88;;;5235:18;;:::i;5297:275::-;5368:2;5362:9;5433:2;5414:13;;-1:-1:-1;;5410:27:1;5398:40;;-1:-1:-1;;;;;5453:34:1;;5489:22;;;5450:62;5447:88;;;5515:18;;:::i;:::-;5551:2;5544:22;5297:275;;-1:-1:-1;5297:275:1:o;5577:531::-;5620:5;5673:3;5666:4;5658:6;5654:17;5650:27;5640:55;;5691:1;5688;5681:12;5640:55;5727:6;5714:20;-1:-1:-1;;;;;5749:2:1;5746:26;5743:52;;;5775:18;;:::i;:::-;5819:55;5862:2;5843:13;;-1:-1:-1;;5839:27:1;5868:4;5835:38;5819:55;:::i;:::-;5899:2;5890:7;5883:19;5945:3;5938:4;5933:2;5925:6;5921:15;5917:26;5914:35;5911:55;;;5962:1;5959;5952:12;5911:55;6027:2;6020:4;6012:6;6008:17;6001:4;5992:7;5988:18;5975:55;6075:1;6050:16;;;6068:4;6046:27;6039:38;;;;6054:7;5577:531;-1:-1:-1;;;5577:531:1:o;6113:390::-;6191:6;6199;6252:2;6240:9;6231:7;6227:23;6223:32;6220:52;;;6268:1;6265;6258:12;6220:52;6304:9;6291:23;6281:33;;6365:2;6354:9;6350:18;6337:32;-1:-1:-1;;;;;6384:6:1;6381:30;6378:50;;;6424:1;6421;6414:12;6378:50;6447;6489:7;6480:6;6469:9;6465:22;6447:50;:::i;:::-;6437:60;;;6113:390;;;;;:::o;6508:131::-;-1:-1:-1;;;;;6583:31:1;;6573:42;;6563:70;;6629:1;6626;6619:12;6644:367;6707:8;6717:6;6771:3;6764:4;6756:6;6752:17;6748:27;6738:55;;6789:1;6786;6779:12;6738:55;-1:-1:-1;6812:20:1;;-1:-1:-1;;;;;6844:30:1;;6841:50;;;6887:1;6884;6877:12;6841:50;6924:4;6916:6;6912:17;6900:29;;6984:3;6977:4;6967:6;6964:1;6960:14;6952:6;6948:27;6944:38;6941:47;6938:67;;;7001:1;6998;6991:12;7016:572;7111:6;7119;7127;7180:2;7168:9;7159:7;7155:23;7151:32;7148:52;;;7196:1;7193;7186:12;7148:52;7235:9;7222:23;7254:31;7279:5;7254:31;:::i;:::-;7304:5;-1:-1:-1;7360:2:1;7345:18;;7332:32;-1:-1:-1;;;;;7376:30:1;;7373:50;;;7419:1;7416;7409:12;7373:50;7458:70;7520:7;7511:6;7500:9;7496:22;7458:70;:::i;:::-;7016:572;;7547:8;;-1:-1:-1;7432:96:1;;-1:-1:-1;;;;7016:572:1:o;7593:658::-;7764:2;7816:21;;;7886:13;;7789:18;;;7908:22;;;7735:4;;7764:2;7987:15;;;;7961:2;7946:18;;;7735:4;8030:195;8044:6;8041:1;8038:13;8030:195;;;8109:13;;-1:-1:-1;;;;;8105:39:1;8093:52;;8200:15;;;;8165:12;;;;8141:1;8059:9;8030:195;;;-1:-1:-1;8242:3:1;;7593:658;-1:-1:-1;;;;;;7593:658:1:o;8256:160::-;8321:20;;8377:13;;8370:21;8360:32;;8350:60;;8406:1;8403;8396:12;8350:60;8256:160;;;:::o;8421:709::-;8531:6;8539;8547;8555;8563;8616:3;8604:9;8595:7;8591:23;8587:33;8584:53;;;8633:1;8630;8623:12;8584:53;8672:9;8659:23;8691:31;8716:5;8691:31;:::i;:::-;8741:5;-1:-1:-1;8793:2:1;8778:18;;8765:32;;-1:-1:-1;8848:2:1;8833:18;;8820:32;-1:-1:-1;;;;;8864:30:1;;8861:50;;;8907:1;8904;8897:12;8861:50;8946:70;9008:7;8999:6;8988:9;8984:22;8946:70;:::i;:::-;9035:8;;-1:-1:-1;8920:96:1;-1:-1:-1;9089:35:1;;-1:-1:-1;9120:2:1;9105:18;;9089:35;:::i;:::-;9079:45;;8421:709;;;;;;;;:::o;9327:1003::-;9415:6;9468:2;9456:9;9447:7;9443:23;9439:32;9436:52;;;9484:1;9481;9474:12;9436:52;9524:9;9511:23;-1:-1:-1;;;;;9594:2:1;9586:6;9583:14;9580:34;;;9610:1;9607;9600:12;9580:34;9633:22;;;;9689:4;9671:16;;;9667:27;9664:47;;;9707:1;9704;9697:12;9664:47;9740:2;9734:9;9782:4;9774:6;9770:17;9837:6;9825:10;9822:22;9817:2;9805:10;9802:18;9799:46;9796:72;;;9848:18;;:::i;:::-;9884:2;9877:22;9921:16;;9946:31;9921:16;9946:31;:::i;:::-;10001:5;9993:6;9986:21;;10061:2;10057;10053:11;10040:25;10035:2;10027:6;10023:15;10016:50;10120:2;10116;10112:11;10099:25;10094:2;10086:6;10082:15;10075:50;10171:2;10167;10163:11;10150:25;10200:2;10190:8;10187:16;10184:36;;;10216:1;10213;10206:12;10184:36;10253:45;10290:7;10279:8;10275:2;10271:17;10253:45;:::i;:::-;10248:2;10236:15;;10229:70;-1:-1:-1;10240:6:1;9327:1003;-1:-1:-1;;;;;9327:1003:1:o;10335:156::-;10401:20;;10461:4;10450:16;;10440:27;;10430:55;;10481:1;10478;10471:12;10496:713;10616:6;10624;10632;10640;10648;10656;10709:3;10697:9;10688:7;10684:23;10680:33;10677:53;;;10726:1;10723;10716:12;10677:53;10762:9;10749:23;10739:33;;10791:36;10823:2;10812:9;10808:18;10791:36;:::i;:::-;10781:46;;10874:2;10863:9;10859:18;10846:32;10836:42;;10925:2;10914:9;10910:18;10897:32;10887:42;;10980:3;10969:9;10965:19;10952:33;-1:-1:-1;;;;;11000:6:1;10997:30;10994:50;;;11040:1;11037;11030:12;10994:50;11079:70;11141:7;11132:6;11121:9;11117:22;11079:70;:::i;:::-;10496:713;;;;-1:-1:-1;10496:713:1;;-1:-1:-1;10496:713:1;;11168:8;;10496:713;-1:-1:-1;;;10496:713:1:o;11214:183::-;11274:4;-1:-1:-1;;;;;11299:6:1;11296:30;11293:56;;;11329:18;;:::i;:::-;-1:-1:-1;11374:1:1;11370:14;11386:4;11366:25;;11214:183::o;11402:1048::-;11461:5;11509:4;11497:9;11492:3;11488:19;11484:30;11481:50;;;11527:1;11524;11517:12;11481:50;11549:22;;:::i;:::-;11540:31;;11607:9;11594:23;-1:-1:-1;;;;;11632:6:1;11629:30;11626:50;;;11672:1;11669;11662:12;11626:50;11695:22;;11748:4;11740:13;;11736:23;-1:-1:-1;11726:51:1;;11773:1;11770;11763:12;11726:51;11809:2;11796:16;11831:4;11855:60;11871:43;11911:2;11871:43;:::i;:::-;11855:60;:::i;:::-;11949:15;;;12031:1;12027:10;;;;12019:19;;12015:28;;;11980:12;;;;12055:15;;;12052:35;;;12083:1;12080;12073:12;12052:35;12107:11;;;;12127:223;12143:6;12138:3;12135:15;12127:223;;;12225:3;12212:17;12242:33;12267:7;12242:33;:::i;:::-;12288:20;;12160:12;;;;12328;;;;12127:223;;;12359:20;;-1:-1:-1;12424:18:1;;;12411:32;12395:14;;;12388:56;;;;-1:-1:-1;12366:5:1;11402:1048;-1:-1:-1;;11402:1048:1:o;12455:1067::-;12514:5;12553:9;12548:3;12544:19;12583:4;12579:2;12575:13;12572:33;;;12601:1;12598;12591:12;12572:33;12623:22;;:::i;:::-;12614:31;;12682:9;12669:23;12701:33;12726:7;12701:33;:::i;:::-;12743:22;;12797:35;12828:2;12813:18;;12797:35;:::i;:::-;12792:2;12785:5;12781:14;12774:59;12884:2;12873:9;12869:18;12856:32;-1:-1:-1;;;;;12948:2:1;12940:6;12937:14;12934:34;;;12964:1;12961;12954:12;12934:34;13000:46;13042:3;13033:6;13022:9;13018:22;13000:46;:::i;:::-;12995:2;12984:14;;12977:70;13081:2;-1:-1:-1;;13063:16:1;;13059:25;13056:45;;;13097:1;13094;13087:12;13056:45;13125:22;;:::i;:::-;13110:37;;13199:2;13188:9;13184:18;13171:32;13156:47;;13212:33;13237:7;13212:33;:::i;:::-;13270:7;13261;13254:24;13310:7;13305:2;13298:5;13294:14;13287:31;13371:3;13360:9;13356:19;13343:33;13327:49;;13401:2;13391:8;13388:16;13385:36;;;13417:1;13414;13407:12;13385:36;;;13454:61;13511:3;13500:8;13489:9;13485:24;13454:61;:::i;:::-;13448:3;13441:5;13437:15;13430:86;;12455:1067;;;;:::o;13527:355::-;13616:6;13669:2;13657:9;13648:7;13644:23;13640:32;13637:52;;;13685:1;13682;13675:12;13637:52;13725:9;13712:23;-1:-1:-1;;;;;13750:6:1;13747:30;13744:50;;;13790:1;13787;13780:12;13744:50;13813:63;13868:7;13859:6;13848:9;13844:22;13813:63;:::i;13887:161::-;13952:5;13997:3;13988:6;13983:3;13979:16;13975:26;13972:46;;;14014:1;14011;14004:12;13972:46;-1:-1:-1;14036:6:1;13887:161;-1:-1:-1;13887:161:1:o;14053:366::-;14144:6;14197:2;14185:9;14176:7;14172:23;14168:32;14165:52;;;14213:1;14210;14203:12;14165:52;14253:9;14240:23;-1:-1:-1;;;;;14278:6:1;14275:30;14272:50;;;14318:1;14315;14308:12;14272:50;14341:72;14405:7;14396:6;14385:9;14381:22;14341:72;:::i;14424:903::-;14700:4;14729:2;14758;14747:9;14740:21;14784:56;14836:2;14825:9;14821:18;14813:6;14784:56;:::i;:::-;14897:22;;;14859:2;14877:18;;;14870:50;;;;14969:13;;14991:22;;;15067:15;;;;15029;;;15100:1;15110:191;15124:6;15121:1;15118:13;15110:191;;;15173:48;15217:3;15208:6;15202:13;2785:12;;2773:25;;2847:4;2836:16;;;2830:23;2814:14;;2807:47;2709:151;15173:48;15276:15;;;;15241:12;;;;15146:1;15139:9;15110:191;;;-1:-1:-1;15318:3:1;;14424:903;-1:-1:-1;;;;;;;;14424:903:1:o;15332:640::-;15436:6;15444;15452;15460;15513:2;15501:9;15492:7;15488:23;15484:32;15481:52;;;15529:1;15526;15519:12;15481:52;15568:9;15555:23;15587:31;15612:5;15587:31;:::i;:::-;15637:5;-1:-1:-1;15689:2:1;15674:18;;15661:32;;-1:-1:-1;15744:2:1;15729:18;;15716:32;-1:-1:-1;;;;;15760:30:1;;15757:50;;;15803:1;15800;15793:12;15757:50;15842:70;15904:7;15895:6;15884:9;15880:22;15842:70;:::i;:::-;15332:640;;;;-1:-1:-1;15931:8:1;-1:-1:-1;;;;15332:640:1:o;16415:318::-;16490:6;16498;16506;16559:2;16547:9;16538:7;16534:23;16530:32;16527:52;;;16575:1;16572;16565:12;16527:52;16611:9;16598:23;16588:33;;16640:36;16672:2;16661:9;16657:18;16640:36;:::i;:::-;16630:46;;16723:2;16712:9;16708:18;16695:32;16685:42;;16415:318;;;;;:::o;16738:315::-;16806:6;16814;16867:2;16855:9;16846:7;16842:23;16838:32;16835:52;;;16883:1;16880;16873:12;16835:52;16919:9;16906:23;16896:33;;16979:2;16968:9;16964:18;16951:32;16992:31;17017:5;16992:31;:::i;:::-;17042:5;17032:15;;;16738:315;;;;;:::o;17058:248::-;17126:6;17134;17187:2;17175:9;17166:7;17162:23;17158:32;17155:52;;;17203:1;17200;17193:12;17155:52;-1:-1:-1;;17226:23:1;;;17296:2;17281:18;;;17268:32;;-1:-1:-1;17058:248:1:o;17311:247::-;17370:6;17423:2;17411:9;17402:7;17398:23;17394:32;17391:52;;;17439:1;17436;17429:12;17391:52;17478:9;17465:23;17497:31;17522:5;17497:31;:::i;17801:461::-;18063:1;18059;18054:3;18050:11;18046:19;18038:6;18034:32;18023:9;18016:51;18103:6;18098:2;18087:9;18083:18;18076:34;18146:6;18141:2;18130:9;18126:18;18119:34;18189:3;18184:2;18173:9;18169:18;18162:31;17997:4;18210:46;18251:3;18240:9;18236:19;18228:6;18210:46;:::i;18267:891::-;18351:6;18382:2;18425;18413:9;18404:7;18400:23;18396:32;18393:52;;;18441:1;18438;18431:12;18393:52;18481:9;18468:23;-1:-1:-1;;;;;18506:6:1;18503:30;18500:50;;;18546:1;18543;18536:12;18500:50;18569:22;;18622:4;18614:13;;18610:27;-1:-1:-1;18600:55:1;;18651:1;18648;18641:12;18600:55;18687:2;18674:16;18710:60;18726:43;18766:2;18726:43;:::i;18710:60::-;18804:15;;;18886:1;18882:10;;;;18874:19;;18870:28;;;18835:12;;;;18910:19;;;18907:39;;;18942:1;18939;18932:12;18907:39;18966:11;;;;18986:142;19002:6;18997:3;18994:15;18986:142;;;19068:17;;19056:30;;19019:12;;;;19106;;;;18986:142;;;19147:5;18267:891;-1:-1:-1;;;;;;;18267:891:1:o;19345:702::-;19472:6;19480;19488;19541:2;19529:9;19520:7;19516:23;19512:32;19509:52;;;19557:1;19554;19547:12;19509:52;19597:9;19584:23;-1:-1:-1;;;;;19667:2:1;19659:6;19656:14;19653:34;;;19683:1;19680;19673:12;19653:34;19706:72;19770:7;19761:6;19750:9;19746:22;19706:72;:::i;:::-;19696:82;;19831:2;19820:9;19816:18;19803:32;19787:48;;19860:2;19850:8;19847:16;19844:36;;;19876:1;19873;19866:12;19844:36;;19915:72;19979:7;19968:8;19957:9;19953:24;19915:72;:::i;20052:127::-;20113:10;20108:3;20104:20;20101:1;20094:31;20144:4;20141:1;20134:15;20168:4;20165:1;20158:15;20184:248;20333:2;20318:18;;20366:1;20355:13;;20345:47;;20372:18;;:::i;:::-;20401:25;;;20184:248;:::o;20437:813::-;20626:2;20615:9;20608:21;20589:4;20665:1;20661;20656:3;20652:11;20648:19;20722:2;20713:6;20707:13;20703:22;20698:2;20687:9;20683:18;20676:50;20794:2;20786:6;20782:15;20776:22;20769:30;20762:38;20757:2;20746:9;20742:18;20735:66;20848:2;20840:6;20836:15;20830:22;20888:4;20883:2;20872:9;20868:18;20861:32;20916:52;20963:3;20952:9;20948:19;20934:12;20916:52;:::i;:::-;20902:66;;21040:2;21033;21025:6;21021:15;21015:22;21009:29;21005:38;20999:3;20988:9;20984:19;20977:67;21093:3;21085:6;21081:16;21075:23;21053:45;;21168:2;21164:7;21152:9;21144:6;21140:22;21136:36;21129:4;21118:9;21114:20;21107:66;21190:54;21237:6;21221:14;21190:54;:::i;21255:437::-;21341:6;21349;21402:2;21390:9;21381:7;21377:23;21373:32;21370:52;;;21418:1;21415;21408:12;21370:52;21458:9;21445:23;-1:-1:-1;;;;;21483:6:1;21480:30;21477:50;;;21523:1;21520;21513:12;21477:50;21562:70;21624:7;21615:6;21604:9;21600:22;21562:70;:::i;:::-;21651:8;;21536:96;;-1:-1:-1;21255:437:1;-1:-1:-1;;;;21255:437:1:o;21971:380::-;22050:1;22046:12;;;;22093;;;22114:61;;22168:4;22160:6;22156:17;22146:27;;22114:61;22221:2;22213:6;22210:14;22190:18;22187:38;22184:161;;22267:10;22262:3;22258:20;22255:1;22248:31;22302:4;22299:1;22292:15;22330:4;22327:1;22320:15;22482:545;22584:2;22579:3;22576:11;22573:448;;;22620:1;22645:5;22641:2;22634:17;22690:4;22686:2;22676:19;22760:2;22748:10;22744:19;22741:1;22737:27;22731:4;22727:38;22796:4;22784:10;22781:20;22778:47;;;-1:-1:-1;22819:4:1;22778:47;22874:2;22869:3;22865:12;22862:1;22858:20;22852:4;22848:31;22838:41;;22929:82;22947:2;22940:5;22937:13;22929:82;;;22992:17;;;22973:1;22962:13;22929:82;;;22933:3;;;22482:545;;;:::o;23203:1352::-;23329:3;23323:10;-1:-1:-1;;;;;23348:6:1;23345:30;23342:56;;;23378:18;;:::i;:::-;23407:97;23497:6;23457:38;23489:4;23483:11;23457:38;:::i;:::-;23451:4;23407:97;:::i;:::-;23559:4;;23623:2;23612:14;;23640:1;23635:663;;;;24342:1;24359:6;24356:89;;;-1:-1:-1;24411:19:1;;;24405:26;24356:89;-1:-1:-1;;23160:1:1;23156:11;;;23152:24;23148:29;23138:40;23184:1;23180:11;;;23135:57;24458:81;;23605:944;;23635:663;22429:1;22422:14;;;22466:4;22453:18;;-1:-1:-1;;23671:20:1;;;23789:236;23803:7;23800:1;23797:14;23789:236;;;23892:19;;;23886:26;23871:42;;23984:27;;;;23952:1;23940:14;;;;23819:19;;23789:236;;;23793:3;24053:6;24044:7;24041:19;24038:201;;;24114:19;;;24108:26;-1:-1:-1;;24197:1:1;24193:14;;;24209:3;24189:24;24185:37;24181:42;24166:58;24151:74;;24038:201;-1:-1:-1;;;;;24285:1:1;24269:14;;;24265:22;24252:36;;-1:-1:-1;23203:1352:1:o;24560:127::-;24621:10;24616:3;24612:20;24609:1;24602:31;24652:4;24649:1;24642:15;24676:4;24673:1;24666:15;24692:125;24757:9;;;24778:10;;;24775:36;;;24791:18;;:::i;25121:208::-;25233:9;25270:53;25308:14;25301:5;25270:53;:::i;25334:127::-;25395:10;25390:3;25386:20;25383:1;25376:31;25426:4;25423:1;25416:15;25450:4;25447:1;25440:15;25466:135;25505:3;25526:17;;;25523:43;;25546:18;;:::i;:::-;-1:-1:-1;25593:1:1;25582:13;;25466:135::o;25606:128::-;25673:9;;;25694:11;;;25691:37;;;25708:18;;:::i;25739:655::-;25907:2;25959:21;;;26029:13;;25932:18;;;26051:22;;;25878:4;26116:17;;;26156:16;;;25878:4;;25907:2;26104;26089:18;;;25878:4;26200:168;26214:6;26211:1;26208:13;26200:168;;;26275:13;;26263:26;;26356:1;26344:14;;;;26309:12;;;;26229:9;26200:168;;27077:245;27223:2;27208:18;;27256:1;27245:13;;27235:47;;27262:18;;:::i;27327:168::-;27400:9;;;27431;;27448:15;;;27442:22;;27428:37;27418:71;;27469:18;;:::i;27500:217::-;27540:1;27566;27556:132;;27610:10;27605:3;27601:20;27598:1;27591:31;27645:4;27642:1;27635:15;27673:4;27670:1;27663:15;27556:132;-1:-1:-1;27702:9:1;;27500:217::o;28332:388::-;28519:25;;;-1:-1:-1;;;;;28580:32:1;;28575:2;28560:18;;28553:60;28649:2;28644;28629:18;;28622:30;;;-1:-1:-1;;28669:45:1;;28695:18;;28687:6;28669:45;:::i;29720:127::-;29781:10;29776:3;29772:20;29769:1;29762:31;29812:4;29809:1;29802:15;29836:4;29833:1;29826:15

Swarm Source

ipfs://fd21334ef3483ae8631dcf3ffb394cdffd811bdabfe2a857263421b3df8eb6f9

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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