ETH Price: $3,673.57 (+1.32%)

Token

ERC-20: ATS WARBONDS (WARBONDS)
 

Overview

Max Total Supply

4,186 WARBONDS

Holders

616

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

0x5bab041808c3d041063f3973a26a483b0d3ac891
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
WarBonds

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-03-30
*/

// SPDX-License-Identifier: MIT

// War Bonds by ATS. Written by NiftyLabs (https://niftylabs.dev/).

//@@@@@ &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/ @@@@@ 
//@   @(&... ..... .. .. .. ..  ....   .... ...,...... ............. %@@@@@@@@@#..  ....... ....   ........  . .......,.  . . .... .... ......%*@   @ 
//&&@%@ ...   ...... .... .. . .. ... ... .. ..... .. ...  . ,@%.          .,/(,/*//@................ ..  ... .........   .  ...........  .... .@%@&& 
//@ @. ..@  # @      @@    @   &           @ ....... ......@.(%(.          ,/(**//(,    @@*.. . ...  . . ....@   .(      @&    @         /     ,. @ @ 
//@ @...@*   @./   @  .%.  /  # @  /& @   @(... . .  ..(@.    #/.         .....,,,/@ . ,@/   &@.............% .  @. #  @   ,*     @ @   ,.(   @ ..@ @ 
//@ @. # @@   .@   @  @@ & @  @.@  . .@     . .... .@#  *%. .  (. *&,    ..*#, ,*//@ . . . . @   @%  .. . ..#&&   (,.  @  (* @ @  #.@     @   ....@ @ 
//@ @. . ..   ........ ..,. . ....  .  .. ..  . .@%  @..   .. /*#,.     , */%(,,#/ @ ...  ,.  ..*,  @,.... ..... ...  ..  . . .   ..,. ...., .....@ @ 
//@ @..... ...@  %  .@#   @%*@(  @# @ ... .....@  #.  ..   .   / (,    ,    ,((.*./% .. /@@.  .,   @  #@... ......&.  ,  @@   (@ @@  .@ ..........@ @ 
//@ @. ..  . .(  @*  &@@    @ @    @%. .. . .@  @ .   ..   .   @(#(,  /   /.,#.@@.//*,,/@%.*  ..   ,.   #@. ... . @  (@  &@@    &.@    &# ...... .@ @ 
//@ @  .. . ..@  @   .@#@   @.@  @@  ..... @* #   .   .**@#%@(*., ....,,*.*/..,**##(#,#@#%,   ..   ,.  #  @.  .   @  .(  (@.@   &.@  ,@.  ........@ @ 
//@ @..   ...... ..  .. .. ...   ..... .. @  &.. ..   ..  @@&/&@/*,      / ,  ,@@% / /(& . .  ...   .  ,.@ *&. . . .. ..  .. .. ......  ... .. ...@ @ 
//@ @.. .. . .. . ..,##. . .  ....   ....@  .... . .  .   . % ,.  .**(@@&*,(*(&/#.  .@@. . .. ... . .  ...@  @..... .  ... ....&@&,..  ... .. . . @ @ 
//@ @... .......@ .  @@  * @. .    . .. @  .. .. . ...    . ./ # @   ***@&##@*,/@* ,*  . . ..   . . .... ,.@  @... .......@ @   /   & @..... .  ..@ @ 
//@ @...... ..@(  % *  ///  ,@.. ......@  /..  ... ...  ... .. &./*.#* .,.  ..,, & .     .  ..  ... ..,  .,.@ @,.  . . .  .  *   /&%*   # ...    .@ @ 
//@ @....... @.    @#@# #%&   @ . ... .@ @ ..   .   ..  .,   &%,,(@,/  ... .,.., *//**@..   ,.   ,.  ,.  .*.   @........#/ @ %(@@#.@@(    ... ... @ @ 
//@ @.. .  . @.  @ @@@@@/&    &.......@  / ,.  .,   ,. *%*..   ,%@,,@(@. /&,%&#/@((/,.*%,**,  &%%@   ,,   *  @ @ .   ...&#  .#@@@@@&*   ..... ... @ @ 
//@ @....  ...@#  *&@  #*   *@  .. .. @    ,.  .,   ,@,.#, ,*@ *,  .%  #*#@@&%#/ ..%... .&,(. / /,   ,,  ,,  @ (( . ... .,*  @@   @%    . ...  . .@ @ 
//@ @..  .. ....@ . *%&  . @. ....  ..@   ..,  ,,  ., (, ,/ ,. ,.**%  #*( */&%*/(,,./*. */#@ .%,%*   *,  ,., @ *#. . . ....(*  @&@  &.#.. ....  ..@ @ 
//@ @  ........ . . .// . ...... .  . @   ,... , . (  ,&*, *,@.,.* .*#&( ,, &@*    .., **,,,,(&,, /, .,..* * @ &............  ........  ..... ... @ @ 
//@ @.  , .. ...... ... .. ... .. . ..(% @* ..,  ,.&  (&*(,.@.*(@,  ,  ,,, *@@  &  , ,**,,/*#**, . .., ,.* *.* @ . .  ...  ..,.,. .  . .,, .. ....@ @ 
//@ @..&(*&.%.../@ %*%%( . /@.@,.%%%,..@  , .,*  .,,*.@,  ,*@ @**#@* . . ,,& ,  ./ ,( ,.*,*(#%*,.%& ,. ,,. ,@ .@ .  ..    ...... .. .   ... . . ..& @ 
//@ @. %#/,.&././&*,..&.#(/..#. /#./....@ @  **  .* ,.*# % ,. @*./*@,,(#&&/.(%   / .,*,,,*,%#/* *% .&( ./     @. ... .# # *(*..  . ..,   ... .. ..@ @ 
//@ @..%#%#(%(#*,.*,%#% (/.#%(%,.##(.. .#& @ **  ,@/.,,/,(  /. **,,@* (%..#  .     /,,,*,*.**@*/(,,# @ ,/    @.... ...**(.#//##. #,# .#*/# #.,/ ..& @ 
//@ @ .,, .....,.........., .....,,....../@ @/*  ,@,&/,(   . *.  &..*@*   (     , .@ ,*,,,@*/.*,,/     ./.  @  ...  .. . .. .... .. .. . .. . ..  & @ 
//@ &. ....   ..  ........ ..... ..... ....@  /  *#/,%        /*@.,.##,  .( *.,   @..,..*@.*/@,,(...  #,@ .@.. ....  ...,.(.%.......  ,(*#...... .& @ 
//@ &.... ..... ..........  .. .....   .. . @% % @.&       .@   ..*@.., # ,  %,   .     *.@.,(,#      (  @.. .  ..... . .... ...  . . ........ . .& @ 
//@ & .. @  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&@&&%  @... & @ 
//@ &.. .# %  @  @ ,@  @@ .@*@  @@  &  @ ,@  @*@  @   @  @  @@  @*@  @  % @  @ .@  @ @  @@# @  @  @@ @  &#@  ( & @( ,  @  @ (@   @@@  @ ,  & @....& @ 
//@ &../@@@@  @  & ,#  @@@@  /  @&  @  @  %  @@   @      @  %#  @@  @(@  @#  @@@@  @@&@@/ &  & *.   @@@  @@  . &  & ,, %  @ .@@@  /&  @    @@@@/ .& @ 
//@@@@@@@..%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@/,.@@@@@@@

// File: operator-filter-registry/src/lib/Constants.sol
pragma solidity ^0.8.17;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

// File: operator-filter-registry/src/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}

// File: operator-filter-registry/src/UpdatableOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  UpdatableOperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry. This contract allows the Owner to update the
 *         OperatorFilterRegistry address via updateOperatorFilterRegistryAddress, including to the zero address,
 *         which will bypass registry checks.
 *         Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 */
abstract contract UpdatableOperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);
    /// @dev Emitted when someone other than the owner is trying to call an only owner function.
    error OnlyOwner();

    event OperatorFilterRegistryAddressUpdated(address newRegistry);

    IOperatorFilterRegistry public operatorFilterRegistry;

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe) {
        IOperatorFilterRegistry registry = IOperatorFilterRegistry(_registry);
        operatorFilterRegistry = registry;
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(registry).code.length > 0) {
            if (subscribe) {
                registry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    registry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    registry.register(address(this));
                }
            }
        }
    }

    /**
     * @dev A helper function to check if the operator is allowed.
     */
    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    /**
     * @dev A helper function to check if the operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be bypassed. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public virtual {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
        emit OperatorFilterRegistryAddressUpdated(newRegistry);
    }

    /**
     * @dev Assume the contract has an owner, but leave specific Ownable implementation up to inheriting contract.
     */
    function owner() public view virtual returns (address);

    /**
     * @dev A helper function to check if the operator is allowed.
     */
    function _checkFilterOperator(address operator) internal view virtual {
        IOperatorFilterRegistry registry = operatorFilterRegistry;
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(registry) != address(0) && address(registry).code.length > 0) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (!registry.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

// File: operator-filter-registry/src/RevokableOperatorFilterer.sol


pragma solidity ^0.8.13;



/**
 * @title  RevokableOperatorFilterer
 * @notice This contract is meant to allow contracts to permanently skip OperatorFilterRegistry checks if desired. The
 *         Registry itself has an "unregister" function, but if the contract is ownable, the owner can re-register at
 *         any point. As implemented, this abstract contract allows the contract owner to permanently skip the
 *         OperatorFilterRegistry checks by calling revokeOperatorFilterRegistry. Once done, the registry
 *         address cannot be further updated.
 *         Note that OpenSea will still disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */
abstract contract RevokableOperatorFilterer is UpdatableOperatorFilterer {
    /// @dev Emitted when the registry has already been revoked.
    error RegistryHasBeenRevoked();
    /// @dev Emitted when the initial registry address is attempted to be set to the zero address.
    error InitialRegistryAddressCannotBeZeroAddress();

    event OperatorFilterRegistryRevoked();

    bool public isOperatorFilterRegistryRevoked;

    /// @dev The constructor that is called when the contract is being deployed.
    constructor(address _registry, address subscriptionOrRegistrantToCopy, bool subscribe)
        UpdatableOperatorFilterer(_registry, subscriptionOrRegistrantToCopy, subscribe)
    {
        // don't allow creating a contract with a permanently revoked registry
        if (_registry == address(0)) {
            revert InitialRegistryAddressCannotBeZeroAddress();
        }
    }

    /**
     * @notice Update the address that the contract will make OperatorFilter checks against. When set to the zero
     *         address, checks will be permanently bypassed, and the address cannot be updated again. OnlyOwner.
     */
    function updateOperatorFilterRegistryAddress(address newRegistry) public override {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        operatorFilterRegistry = IOperatorFilterRegistry(newRegistry);
        emit OperatorFilterRegistryAddressUpdated(newRegistry);
    }

    /**
     * @notice Revoke the OperatorFilterRegistry address, permanently bypassing checks. OnlyOwner.
     */
    function revokeOperatorFilterRegistry() public {
        if (msg.sender != owner()) {
            revert OnlyOwner();
        }
        // if registry has been revoked, do not allow further updates
        if (isOperatorFilterRegistryRevoked) {
            revert RegistryHasBeenRevoked();
        }

        // set to zero address to bypass checks
        operatorFilterRegistry = IOperatorFilterRegistry(address(0));
        isOperatorFilterRegistryRevoked = true;
        emit OperatorFilterRegistryRevoked();
    }
}

// File: operator-filter-registry/src/RevokableDefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  RevokableDefaultOperatorFilterer
 * @notice Inherits from RevokableOperatorFilterer and automatically subscribes to the default OpenSea subscription.
 *         Note that OpenSea will disable creator earnings enforcement if filtered operators begin fulfilling orders
 *         on-chain, eg, if the registry is revoked or bypassed.
 */

abstract contract RevokableDefaultOperatorFilterer is RevokableOperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor()
        RevokableOperatorFilterer(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS, CANONICAL_CORI_SUBSCRIPTION, true)
    {}
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

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


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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;


/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/token/ERC1155/IERC1155.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;







/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

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

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_) {
        _setURI(uri_);
    }

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

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: address zero is not a valid owner");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        virtual
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

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

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not token owner or approved"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not token owner or approved"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `amount` tokens of token type `id`.
     */
    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }

        emit TransferSingle(operator, from, address(0), id, amount);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
        }

        emit TransferBatch(operator, from, address(0), ids, amounts);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `ids` and `amounts` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

// File: WarBonds.sol



// War Bonds by ATS. Written by NiftyLabs (https://niftylabs.dev/).

pragma solidity ^0.8.17;








contract WarBonds is ERC1155, Ownable, RevokableDefaultOperatorFilterer {

    string public name_;
    string public symbol_; 

    address public erc20Address;
    address public adminAddress;
    address public signer = 0x2f2A13462f6d4aF64954ee84641D265932849b64;
    address private crossMint = 0xdAb1a1854214684acE522439684a145E62505233;

    bool public isAllowlistClaimActive = false;

    struct TokenData {
        bool buyable;
        uint64 supply;
        uint64 minted;
        string uri;
        uint256 price;
        uint256 erc20Price;
    }

    mapping(uint256 => bool) public validTypes;
    mapping(uint256 => TokenData) public idToTokenData;

    mapping(address => mapping(uint256 => bool)) public allowlistMinted;

    uint256 public paymentPerClaim = 0.0006 ether;
    address public paymentFeeAddress = 0xa69B6935B0F38506b81224B4612d7Ea49A4B0aCC;
    address public withdrawAddress = 0x3978a70Acce93153f524e8fcdcBA1E3ace0aC05B;

    constructor() ERC1155("WarBonds") {
        name_ = "ATS WARBONDS";
        symbol_ = "WARBONDS";     
    }

    function createToken(
        uint256 _id,
        bool _buyable,
        uint64 _supply,
        string memory _uri,
        uint256 _price,
        uint256 _erc20Price
    ) public onlyOwner {
        require(validTypes[_id] == false, "token _id already exists");
        validTypes[_id] = true;

        idToTokenData[_id] = TokenData({
            buyable: _buyable,
            supply: _supply,
            minted: 0,
            uri: _uri,
            price: _price,
            erc20Price: _erc20Price
        });

        emit URI(_uri, _id);
    }

    function changeTokenURI(uint256 _id, string memory _uri) public onlyOwner {
        require(validTypes[_id], "Token doesn't exist yet");

        TokenData storage tokenData = idToTokenData[_id];

        tokenData.uri = _uri;

        emit URI(_uri, _id);
    }

    function changeTokenBuyable(uint256 _id, bool _status) public onlyOwner {
        require(validTypes[_id], "Token doesn't exist yet");

        TokenData storage tokenData = idToTokenData[_id];

        tokenData.buyable = _status;
    }

    function changeTokenPrice(uint256 _id, uint256 _price) public onlyOwner {
        require(validTypes[_id], "Token doesn't exist yet");

        TokenData storage tokenData = idToTokenData[_id];

        tokenData.price = _price;
    }

    function changeTokenERC20Price(uint256 _id, uint256 _price) public onlyOwner {
        require(validTypes[_id], "Token doesn't exist yet");

        TokenData storage tokenData = idToTokenData[_id];

        tokenData.erc20Price = _price;
    }

    function changeTokenSupply(uint256 _id, uint64 _supply) public onlyOwner {
        require(validTypes[_id], "Token doesn't exist yet");
        
        TokenData storage tokenData = idToTokenData[_id];
        require(_supply >= tokenData.supply, "New supply must be greater than current supply");

        tokenData.supply = _supply;
    }

    function reserveToken(uint256 _id, uint256 _amount) public onlyOwner  {
        TokenData storage tokenData = idToTokenData[_id];
        
        require(tokenData.minted + _amount <= tokenData.supply, "Minted out");

        tokenData.minted += uint64(_amount);
        _mint(msg.sender, _id, _amount, "");
    }

    function claimTokensWithAllowlist(bytes calldata _voucher, uint256 _id, uint256 _amount) public  {
        TokenData storage tokenData = idToTokenData[_id];
        
        require(isAllowlistClaimActive, "Allowlist claim is off");
        require(tokenData.minted + _amount <= tokenData.supply, "Minted out");
        require(!allowlistMinted[msg.sender][_id], "Already minted");

        allowlistMinted[msg.sender][_id] = true;

        bytes32 hash = keccak256(abi.encodePacked(msg.sender, _id, _amount));
        require(_verifySignature(signer, hash, _voucher), "Invalid voucher");

        tokenData.minted += uint64(_amount);
        _mint(msg.sender, _id, _amount, "");
    }

    function buyTokensWithEth(uint256 _id, uint256 _amount) public payable {
        TokenData storage tokenData = idToTokenData[_id];

        require(tokenData.price > 0, "Can't buy with ETH");
        require(msg.value >= ((tokenData.price * _amount) + (paymentPerClaim * _amount)), "Not enough eth");
        require(tokenData.buyable, "Not buyable");

        require(tokenData.minted + _amount <= tokenData.supply, "Minted out");
        require(_amount > 0, "Can't buy 0");

        tokenData.minted += uint64(_amount);

        _mint(msg.sender, _id, _amount, "");

        _sendPaymentEth(paymentPerClaim * _amount);
    }

    function buyTokensWithCreditCard(address wallet, uint256 _id, uint256 _amount) public payable {
        TokenData storage tokenData = idToTokenData[_id];

        require(msg.sender == crossMint, "Crossmint only");
        require(tokenData.price > 0, "Can't buy with ETH");
        require(msg.value >= ((tokenData.price * _amount) + (paymentPerClaim * _amount)), "Not enough eth");
        require(tokenData.buyable, "Not buyable");

        require(tokenData.minted + _amount <= tokenData.supply, "Minted out");
        require(_amount > 0, "Can't buy 0");

        tokenData.minted += uint64(_amount);

        _mint(wallet, _id, _amount, "");

        _sendPaymentEth(paymentPerClaim * _amount);
    }

    function buyTokensWithERC20(uint256 _id, uint256 _amount) public payable {
        TokenData storage tokenData = idToTokenData[_id];

        require(tokenData.erc20Price > 0, "Can't buy with ERC20");
        require(tokenData.minted + _amount <= tokenData.supply, "Minted out");
        require(tokenData.buyable, "Not buyable");

        require(_amount > 0, "Can't buy 0");
        require(msg.value >= (paymentPerClaim*_amount), "No payment fee");

        IERC20(erc20Address).transferFrom(
            msg.sender,
            withdrawAddress,
            tokenData.erc20Price * _amount
        );

        tokenData.minted += uint64(_amount);
        _mint(msg.sender, _id, _amount, "");

        _sendPaymentEth(paymentPerClaim * _amount);
    }

    function mintBatch(
        uint256[] memory _ids,
        uint256[] memory _quantity
    ) external onlyOwner {
        _mintBatch(owner(), _ids, _quantity, "");
    }

    function burnForAddress(uint256 _id, address _address) external {
        require(msg.sender == adminAddress, "Invalid burner address");
        _burn(_address, _id, 1);
    }

    function setERC20Address(address _erc20Address) external onlyOwner {
        erc20Address = _erc20Address;
    }

    function setAdminAddress(address _adminAddress) external onlyOwner {
        adminAddress = _adminAddress;
    }

    function _verifySignature(address _signer, bytes32 _hash, bytes memory _signature) private pure returns (bool) {
        return _signer == ECDSA.recover(ECDSA.toEthSignedMessageHash(_hash), _signature);
    }

    function setSigner(address _signer) external onlyOwner {
        signer = _signer;
    }

    function setWithdrawAddress(address _address) external onlyOwner {
        withdrawAddress = _address;
    }

    function setPaymentFeeAddress(address _address) external onlyOwner {
        paymentFeeAddress = _address;
    }

    function setAllowlistClaimActive() public onlyOwner {
        isAllowlistClaimActive = !isAllowlistClaimActive;
    }

    function updatePaymentFee(uint256 _fee) public onlyOwner {
        paymentPerClaim = _fee;
    }

    function getTokenDataFor(uint256[] calldata ids) external view returns (TokenData[] memory) {

        TokenData[] memory tokenData = new TokenData[](ids.length);
        
        for(uint256 i = 0; i < ids.length; i++)
            tokenData[i] = idToTokenData[ids[i]];

        return tokenData;
    }

    function uri(uint256 _id) public view override returns (string memory) {
        require(validTypes[_id], "URI requested for invalid type");

        TokenData memory tokenData = idToTokenData[_id];

        return string(abi.encodePacked(tokenData.uri, Strings.toString(_id)));
    }

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

    function symbol() public view returns (string memory) {
        return symbol_;
    }

    function _sendPaymentEth(uint256 _value) internal {
        (bool success, ) = payable(paymentFeeAddress).call {value: _value}("");
        require(success);
    }

    function withdraw() public payable onlyOwner {
        (bool success, ) = payable(withdrawAddress).call {value: address(this).balance}("");
        require(success);
    }

    function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
        super.setApprovalForAll(operator, approved);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, uint256 amount, bytes memory data)
        public
        override
        onlyAllowedOperator(from)
    {
        super.safeTransferFrom(from, to, tokenId, amount, data);
    }

    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override onlyAllowedOperator(from) {
        super.safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    function owner() public view override(Ownable, UpdatableOperatorFilterer) returns (address) {
        return Ownable.owner();
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InitialRegistryAddressCannotBeZeroAddress","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"RegistryHasBeenRevoked","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newRegistry","type":"address"}],"name":"OperatorFilterRegistryAddressUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"OperatorFilterRegistryRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"adminAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"allowlistMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_address","type":"address"}],"name":"burnForAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"buyTokensWithCreditCard","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"buyTokensWithERC20","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"buyTokensWithEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"changeTokenBuyable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"changeTokenERC20Price","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"changeTokenPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint64","name":"_supply","type":"uint64"}],"name":"changeTokenSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"string","name":"_uri","type":"string"}],"name":"changeTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_voucher","type":"bytes"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimTokensWithAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"bool","name":"_buyable","type":"bool"},{"internalType":"uint64","name":"_supply","type":"uint64"},{"internalType":"string","name":"_uri","type":"string"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_erc20Price","type":"uint256"}],"name":"createToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"erc20Address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"getTokenDataFor","outputs":[{"components":[{"internalType":"bool","name":"buyable","type":"bool"},{"internalType":"uint64","name":"supply","type":"uint64"},{"internalType":"uint64","name":"minted","type":"uint64"},{"internalType":"string","name":"uri","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"erc20Price","type":"uint256"}],"internalType":"struct WarBonds.TokenData[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"idToTokenData","outputs":[{"internalType":"bool","name":"buyable","type":"bool"},{"internalType":"uint64","name":"supply","type":"uint64"},{"internalType":"uint64","name":"minted","type":"uint64"},{"internalType":"string","name":"uri","type":"string"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"erc20Price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isAllowlistClaimActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOperatorFilterRegistryRevoked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_quantity","type":"uint256[]"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name_","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorFilterRegistry","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentFeeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paymentPerClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"reserveToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeOperatorFilterRegistry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adminAddress","type":"address"}],"name":"setAdminAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setAllowlistClaimActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_erc20Address","type":"address"}],"name":"setERC20Address","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setPaymentFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setWithdrawAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol_","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRegistry","type":"address"}],"name":"updateOperatorFilterRegistryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"updatePaymentFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"validTypes","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdrawAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6080604052600980546001600160a01b0319908116732f2a13462f6d4af64954ee84641d265932849b6417909155600a80546001600160a81b03191673dab1a1854214684ace522439684a145e62505233179055660221b262dd8000600e55600f8054821673a69b6935b0f38506b81224b4612d7ea49a4b0acc17905560108054909116733978a70acce93153f524e8fcdcba1e3ace0ac05b179055348015620000a857600080fd5b506daaeb6d7670e522a718067333cd4e733cc6cdda760b79bafa08df41ecfa224f810dceb6600182828260405180604001604052806008815260200167576172426f6e647360c01b8152506200010481620002e160201b60201c565b506200011033620002f3565b600480546001600160a01b0319166001600160a01b03851690811790915583903b1562000249578115620001a857604051633e9f1edf60e11b81523060048201526001600160a01b038481166024830152821690637d3e3dbe906044015b600060405180830381600087803b1580156200018957600080fd5b505af11580156200019e573d6000803e3d6000fd5b5050505062000249565b6001600160a01b03831615620001ed5760405163a0af290360e01b81523060048201526001600160a01b03848116602483015282169063a0af2903906044016200016e565b604051632210724360e11b81523060048201526001600160a01b03821690634420e48690602401600060405180830381600087803b1580156200022f57600080fd5b505af115801562000244573d6000803e3d6000fd5b505050505b5050506001600160a01b0384169050620002765760405163c49d17ad60e01b815260040160405180910390fd5b505060408051808201909152600c81526b41545320574152424f4e445360a01b602082015260059150620002ab9082620003ea565b50604080518082019091526008815267574152424f4e445360c01b6020820152600690620002da9082620003ea565b50620004b6565b6002620002ef8282620003ea565b5050565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200037057607f821691505b6020821081036200039157634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003e557600081815260208120601f850160051c81016020861015620003c05750805b601f850160051c820191505b81811015620003e157828155600101620003cc565b5050505b505050565b81516001600160401b0381111562000406576200040662000345565b6200041e816200041784546200035b565b8462000397565b602080601f8311600181146200045657600084156200043d5750858301515b600019600386901b1c1916600185901b178555620003e1565b600085815260208120601f198616915b82811015620004875788860151825594840194600190910190840162000466565b5085821015620004a65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61418c80620004c66000396000f3fe6080604052600436106102e35760003560e01c80636d0fd50711610190578063be919dd0116100dc578063e985e9c511610095578063f242432a1161006f578063f242432a14610900578063f2fde38b14610920578063f7eb425014610940578063fc6f94681461095357600080fd5b8063e985e9c514610876578063ecba222a146108bf578063efa492e4146108e057600080fd5b8063be919dd0146107c8578063c0aa4110146107de578063d351cfdc1461080e578063db512e771461082e578063e2b9e1861461084e578063e635d5c11461086357600080fd5b806398764d8311610149578063af17dea611610123578063af17dea614610753578063b0ccc31e14610768578063b7a0816a14610788578063b8d1e532146107a857600080fd5b806398764d83146106e6578063a22cb46514610713578063a2773b111461073357600080fd5b80636d0fd50714610647578063715018a6146106675780637fb3a9a21461067c5780638da5cb5b1461069c5780639169daa1146106b157806395d89b41146106d157600080fd5b80633ab1a4941161024f57806352090713116102085780635965805d116101e25780635965805d146105d25780635ef9432a146105f257806362e8e8ac146106075780636c19e7831461062757600080fd5b8063520907131461055f578063559c2d1b1461057f578063585531b1146105b157600080fd5b80633ab1a494146104b75780633ccfd60b146104d7578063413b9c34146104df57806341bec0d2146104f25780634ce5fb7e146105125780634e1273f41461053257600080fd5b8063205ea1c3116102a1578063205ea1c314610400578063238ac93314610420578063276184ae146104405780632c1e816d146104605780632eb2c2d6146104825780633902e981146104a257600080fd5b8062fdd58e146102e857806301ffc9a71461031b57806306fdde031461034b5780630e89341c1461036d5780631581b6001461038d5780631c129f29146103c5575b600080fd5b3480156102f457600080fd5b50610308610303366004613292565b610973565b6040519081526020015b60405180910390f35b34801561032757600080fd5b5061033b6103363660046132d2565b610a0c565b6040519015158152602001610312565b34801561035757600080fd5b50610360610a5c565b6040516103129190613346565b34801561037957600080fd5b50610360610388366004613359565b610aee565b34801561039957600080fd5b506010546103ad906001600160a01b031681565b6040516001600160a01b039091168152602001610312565b3480156103d157600080fd5b5061033b6103e0366004613292565b600d60209081526000928352604080842090915290825290205460ff1681565b34801561040c57600080fd5b50600f546103ad906001600160a01b031681565b34801561042c57600080fd5b506009546103ad906001600160a01b031681565b34801561044c57600080fd5b506007546103ad906001600160a01b031681565b34801561046c57600080fd5b5061048061047b366004613372565b610c7c565b005b34801561048e57600080fd5b5061048061049d3660046134d6565b610ca6565b3480156104ae57600080fd5b50610480610cd5565b3480156104c357600080fd5b506104806104d2366004613372565b610cfe565b610480610d28565b6104806104ed36600461357f565b610d93565b3480156104fe57600080fd5b5061048061050d366004613372565b610fa0565b34801561051e57600080fd5b5061048061052d3660046135d7565b610fca565b34801561053e57600080fd5b5061055261054d366004613652565b61115a565b6040516103129190613757565b34801561056b57600080fd5b5061048061057a36600461376a565b611283565b34801561058b57600080fd5b5061059f61059a366004613359565b6112e6565b60405161031296959493929190613796565b3480156105bd57600080fd5b50600a5461033b90600160a01b900460ff1681565b3480156105de57600080fd5b506104806105ed3660046137df565b6113b4565b3480156105fe57600080fd5b50610480611475565b34801561061357600080fd5b506104806106223660046137df565b61151a565b34801561063357600080fd5b50610480610642366004613372565b611565565b34801561065357600080fd5b50610480610662366004613801565b61158f565b34801561067357600080fd5b50610480611675565b34801561068857600080fd5b50610480610697366004613824565b611689565b3480156106a857600080fd5b506103ad611719565b3480156106bd57600080fd5b506104806106cc366004613372565b611732565b3480156106dd57600080fd5b5061036061175c565b3480156106f257600080fd5b50610706610701366004613860565b61176b565b60405161031291906138d4565b34801561071f57600080fd5b5061048061072e366004613985565b61193a565b34801561073f57600080fd5b5061048061074e3660046139bc565b61194e565b34801561075f57600080fd5b50610360611ba1565b34801561077457600080fd5b506004546103ad906001600160a01b031681565b34801561079457600080fd5b506104806107a33660046137df565b611c2f565b3480156107b457600080fd5b506104806107c3366004613372565b611c7a565b3480156107d457600080fd5b50610308600e5481565b3480156107ea57600080fd5b5061033b6107f9366004613359565b600b6020526000908152604090205460ff1681565b34801561081a57600080fd5b50610480610829366004613a3a565b611d32565b34801561083a57600080fd5b50610480610849366004613a86565b611d5c565b34801561085a57600080fd5b50610360611db2565b6104806108713660046137df565b611dbf565b34801561088257600080fd5b5061033b610891366004613aab565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b3480156108cb57600080fd5b5060045461033b90600160a01b900460ff1681565b3480156108ec57600080fd5b506104806108fb366004613359565b612001565b34801561090c57600080fd5b5061048061091b366004613ad5565b61200e565b34801561092c57600080fd5b5061048061093b366004613372565b612035565b61048061094e3660046137df565b6120ab565b34801561095f57600080fd5b506008546103ad906001600160a01b031681565b60006001600160a01b0383166109e35760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b506000818152602081815260408083206001600160a01b03861684529091529020545b92915050565b60006001600160e01b03198216636cdb3d1360e11b1480610a3d57506001600160e01b031982166303a24d0760e21b145b80610a0657506301ffc9a760e01b6001600160e01b0319831614610a06565b606060058054610a6b90613b39565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9790613b39565b8015610ae45780601f10610ab957610100808354040283529160200191610ae4565b820191906000526020600020905b815481529060010190602001808311610ac757829003601f168201915b5050505050905090565b6000818152600b602052604090205460609060ff16610b4f5760405162461bcd60e51b815260206004820152601e60248201527f5552492072657175657374656420666f7220696e76616c69642074797065000060448201526064016109da565b6000828152600c60209081526040808320815160c081018352815460ff8116151582526001600160401b036101008204811695830195909552600160481b900490931691830191909152600181018054606084019190610bae90613b39565b80601f0160208091040260200160405190810160405280929190818152602001828054610bda90613b39565b8015610c275780601f10610bfc57610100808354040283529160200191610c27565b820191906000526020600020905b815481529060010190602001808311610c0a57829003601f168201915b505050505081526020016002820154815260200160038201548152505090508060600151610c548461220f565b604051602001610c65929190613b73565b604051602081830303815290604052915050919050565b610c846122a1565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b846001600160a01b0381163314610cc057610cc033612300565b610ccd86868686866123c2565b505050505050565b610cdd6122a1565b600a805460ff60a01b198116600160a01b9182900460ff1615909102179055565b610d066122a1565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b610d306122a1565b6010546040516000916001600160a01b03169047908381818185875af1925050503d8060008114610d7d576040519150601f19603f3d011682016040523d82523d6000602084013e610d82565b606091505b5050905080610d9057600080fd5b50565b6000828152600c60205260409020600a546001600160a01b03163314610dec5760405162461bcd60e51b815260206004820152600e60248201526d43726f73736d696e74206f6e6c7960901b60448201526064016109da565b6000816002015411610e355760405162461bcd60e51b8152602060048201526012602482015271086c2dc4ee840c4eaf240eed2e8d0408aa8960731b60448201526064016109da565b81600e54610e439190613bb8565b828260020154610e539190613bb8565b610e5d9190613bcf565b341015610e9d5760405162461bcd60e51b815260206004820152600e60248201526d09cdee840cadcdeeaced040cae8d60931b60448201526064016109da565b805460ff16610ebe5760405162461bcd60e51b81526004016109da90613be2565b80546001600160401b036101008204811691610ee3918591600160481b900416613bcf565b1115610f015760405162461bcd60e51b81526004016109da90613c07565b60008211610f215760405162461bcd60e51b81526004016109da90613c2b565b805482908290600990610f45908490600160481b90046001600160401b0316613c50565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610f848484846040518060200160405280600081525061240e565b610f9a82600e54610f959190613bb8565b6124e8565b50505050565b610fa86122a1565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b610fd26122a1565b6000868152600b602052604090205460ff16156110315760405162461bcd60e51b815260206004820152601860248201527f746f6b656e205f696420616c726561647920657869737473000000000000000060448201526064016109da565b6000868152600b602090815260408083208054600160ff199091168117909155815160c08101835289151581526001600160401b03898116828601908152828501878152606084018b8152608085018b905260a085018a90528e8952600c90975294909620825181549751955168ffffffffffffffffff1990981690151568ffffffffffffffff00191617610100958316959095029490941770ffffffffffffffff0000000000000000001916600160481b9690911695909502949094178255915190918201906111029082613cbd565b506080820151816002015560a08201518160030155905050857f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b8460405161114a9190613346565b60405180910390a2505050505050565b606081518351146111bf5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016109da565b600083516001600160401b038111156111da576111da61338d565b604051908082528060200260200182016040528015611203578160200160208202803683370190505b50905060005b845181101561127b5761124e85828151811061122757611227613d7c565b602002602001015185838151811061124157611241613d7c565b6020026020010151610973565b82828151811061126057611260613d7c565b602090810291909101015261127481613d92565b9050611209565b509392505050565b6008546001600160a01b031633146112d65760405162461bcd60e51b8152602060048201526016602482015275496e76616c6964206275726e6572206164647265737360501b60448201526064016109da565b6112e281836001612548565b5050565b600c602052600090815260409020805460018201805460ff8316936001600160401b036101008504811694600160481b90041692909161132590613b39565b80601f016020809104026020016040519081016040528092919081815260200182805461135190613b39565b801561139e5780601f106113735761010080835404028352916020019161139e565b820191906000526020600020905b81548152906001019060200180831161138157829003601f168201915b5050505050908060020154908060030154905086565b6113bc6122a1565b6000828152600c6020526040902080546001600160401b0361010082048116916113ef918591600160481b900416613bcf565b111561140d5760405162461bcd60e51b81526004016109da90613c07565b805482908290600990611431908490600160481b90046001600160401b0316613c50565b92506101000a8154816001600160401b0302191690836001600160401b031602179055506114703384846040518060200160405280600081525061240e565b505050565b61147d611719565b6001600160a01b0316336001600160a01b0316146114ae57604051635fc483c560e01b815260040160405180910390fd5b600454600160a01b900460ff16156114d957604051631551a48f60e11b815260040160405180910390fd5b600480546001600160a81b031916600160a01b1790556040517f51e2d870cc2e10853e38dc06fcdae46ad3c3f588f326608803dac6204541ad1690600090a1565b6115226122a1565b6000828152600b602052604090205460ff166115505760405162461bcd60e51b81526004016109da90613dab565b6000918252600c602052604090912060020155565b61156d6122a1565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6115976122a1565b6000828152600b602052604090205460ff166115c55760405162461bcd60e51b81526004016109da90613dab565b6000828152600c6020526040902080546001600160401b036101009091048116908316101561164d5760405162461bcd60e51b815260206004820152602e60248201527f4e657720737570706c79206d7573742062652067726561746572207468616e2060448201526d63757272656e7420737570706c7960901b60648201526084016109da565b80546001600160401b039092166101000268ffffffffffffffff001990921691909117905550565b61167d6122a1565b61168760006126c4565b565b6116916122a1565b6000828152600b602052604090205460ff166116bf5760405162461bcd60e51b81526004016109da90613dab565b6000828152600c60205260409020600181016116db8382613cbd565b50827f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b8360405161170c9190613346565b60405180910390a2505050565b600061172d6003546001600160a01b031690565b905090565b61173a6122a1565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b606060068054610a6b90613b39565b60606000826001600160401b038111156117875761178761338d565b6040519080825280602002602001820160405280156117e657816020015b6040805160c081018252600080825260208083018290529282018190526060808301526080820181905260a082015282526000199092019101816117a55790505b50905060005b8381101561127b57600c600086868481811061180a5761180a613d7c565b60209081029290920135835250818101929092526040908101600020815160c081018352815460ff8116151582526001600160401b036101008204811695830195909552600160481b90049093169183019190915260018101805460608401919061187490613b39565b80601f01602080910402602001604051908101604052809291908181526020018280546118a090613b39565b80156118ed5780601f106118c2576101008083540402835291602001916118ed565b820191906000526020600020905b8154815290600101906020018083116118d057829003601f168201915b505050505081526020016002820154815260200160038201548152505082828151811061191c5761191c613d7c565b6020026020010181905250808061193290613d92565b9150506117ec565b8161194481612300565b6114708383612716565b6000828152600c60205260409020600a54600160a01b900460ff166119ae5760405162461bcd60e51b815260206004820152601660248201527520b63637bbb634b9ba1031b630b4b69034b99037b33360511b60448201526064016109da565b80546001600160401b0361010082048116916119d3918591600160481b900416613bcf565b11156119f15760405162461bcd60e51b81526004016109da90613c07565b336000908152600d6020908152604080832086845290915290205460ff1615611a4d5760405162461bcd60e51b815260206004820152600e60248201526d105b1c9958591e481b5a5b9d195960921b60448201526064016109da565b336000818152600d602090815260408083208784528252808320805460ff191660011790555160609390931b6bffffffffffffffffffffffff19169083015260348201859052605482018490529060740160408051601f198184030181528282528051602091820120600954601f8a018390048302850183019093528884529350611b00926001600160a01b039092169184918a908a908190840183828082843760009201919091525061272192505050565b611b3e5760405162461bcd60e51b815260206004820152600f60248201526e24b73b30b634b2103b37bab1b432b960891b60448201526064016109da565b815483908390600990611b62908490600160481b90046001600160401b0316613c50565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610ccd3385856040518060200160405280600081525061240e565b60068054611bae90613b39565b80601f0160208091040260200160405190810160405280929190818152602001828054611bda90613b39565b8015611c275780601f10611bfc57610100808354040283529160200191611c27565b820191906000526020600020905b815481529060010190602001808311611c0a57829003601f168201915b505050505081565b611c376122a1565b6000828152600b602052604090205460ff16611c655760405162461bcd60e51b81526004016109da90613dab565b6000918252600c602052604090912060030155565b611c82611719565b6001600160a01b0316336001600160a01b031614611cb357604051635fc483c560e01b815260040160405180910390fd5b600454600160a01b900460ff1615611cde57604051631551a48f60e11b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f9f513fe86dc42fdbac355fa4d9b1d5be7b5e6cd2df67e30db8003766568de4769060200160405180910390a150565b611d3a6122a1565b6112e2611d45611719565b8383604051806020016040528060008152506127a0565b611d646122a1565b6000828152600b602052604090205460ff16611d925760405162461bcd60e51b81526004016109da90613dab565b6000918252600c6020526040909120805460ff1916911515919091179055565b60058054611bae90613b39565b6000828152600c602052604090206003810154611e155760405162461bcd60e51b8152602060048201526014602482015273043616e27742062757920776974682045524332360641b60448201526064016109da565b80546001600160401b036101008204811691611e3a918591600160481b900416613bcf565b1115611e585760405162461bcd60e51b81526004016109da90613c07565b805460ff16611e795760405162461bcd60e51b81526004016109da90613be2565b60008211611e995760405162461bcd60e51b81526004016109da90613c2b565b81600e54611ea79190613bb8565b341015611ee75760405162461bcd60e51b815260206004820152600e60248201526d4e6f207061796d656e742066656560901b60448201526064016109da565b60075460105460038301546001600160a01b03928316926323b872dd923392911690611f14908790613bb8565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064016020604051808303816000875af1158015611f68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8c9190613de2565b50805482908290600990611fb1908490600160481b90046001600160401b0316613c50565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550611ff03384846040518060200160405280600081525061240e565b61147082600e54610f959190613bb8565b6120096122a1565b600e55565b846001600160a01b03811633146120285761202833612300565b610ccd86868686866128eb565b61203d6122a1565b6001600160a01b0381166120a25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109da565b610d90816126c4565b6000828152600c6020526040902060028101546120ff5760405162461bcd60e51b8152602060048201526012602482015271086c2dc4ee840c4eaf240eed2e8d0408aa8960731b60448201526064016109da565b81600e5461210d9190613bb8565b82826002015461211d9190613bb8565b6121279190613bcf565b3410156121675760405162461bcd60e51b815260206004820152600e60248201526d09cdee840cadcdeeaced040cae8d60931b60448201526064016109da565b805460ff166121885760405162461bcd60e51b81526004016109da90613be2565b80546001600160401b0361010082048116916121ad918591600160481b900416613bcf565b11156121cb5760405162461bcd60e51b81526004016109da90613c07565b600082116121eb5760405162461bcd60e51b81526004016109da90613c2b565b805482908290600990611fb1908490600160481b90046001600160401b0316613c50565b6060600061221c83612930565b60010190506000816001600160401b0381111561223b5761223b61338d565b6040519080825280601f01601f191660200182016040528015612265576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461226f57509392505050565b336122aa611719565b6001600160a01b0316146116875760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109da565b6004546001600160a01b0316801580159061232557506000816001600160a01b03163b115b156112e257604051633185c44d60e21b81523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa158015612376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239a9190613de2565b6112e257604051633b79c77360e21b81526001600160a01b03831660048201526024016109da565b6001600160a01b0385163314806123de57506123de8533610891565b6123fa5760405162461bcd60e51b81526004016109da90613dff565b6124078585858585612a08565b5050505050565b6001600160a01b0384166124345760405162461bcd60e51b81526004016109da90613e4d565b33600061244085612b9c565b9050600061244d85612b9c565b90506000868152602081815260408083206001600160a01b038b1684529091528120805487929061247f908490613bcf565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46124df83600089898989612be7565b50505050505050565b600f546040516000916001600160a01b03169083908381818185875af1925050503d8060008114612535576040519150601f19603f3d011682016040523d82523d6000602084013e61253a565b606091505b50509050806112e257600080fd5b6001600160a01b0383166125aa5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b60648201526084016109da565b3360006125b684612b9c565b905060006125c384612b9c565b60408051602080820183526000918290528882528181528282206001600160a01b038b168352905220549091508481101561264c5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b60648201526084016109da565b6000868152602081815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090526124df565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6112e2338383612d42565b600061278361277d846040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b83612e22565b6001600160a01b0316846001600160a01b03161490509392505050565b6001600160a01b0384166127c65760405162461bcd60e51b81526004016109da90613e4d565b81518351146127e75760405162461bcd60e51b81526004016109da90613e8e565b3360005b84518110156128835783818151811061280657612806613d7c565b602002602001015160008087848151811061282357612823613d7c565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b03168152602001908152602001600020600082825461286b9190613bcf565b9091555081905061287b81613d92565b9150506127eb565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516128d4929190613ed6565b60405180910390a461240781600087878787612e3e565b6001600160a01b03851633148061290757506129078533610891565b6129235760405162461bcd60e51b81526004016109da90613dff565b6124078585858585612ef9565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061296f5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061299b576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106129b957662386f26fc10000830492506010015b6305f5e10083106129d1576305f5e100830492506008015b61271083106129e557612710830492506004015b606483106129f7576064830492506002015b600a8310610a065760010192915050565b8151835114612a295760405162461bcd60e51b81526004016109da90613e8e565b6001600160a01b038416612a4f5760405162461bcd60e51b81526004016109da90613f04565b3360005b8451811015612b36576000858281518110612a7057612a70613d7c565b602002602001015190506000858381518110612a8e57612a8e613d7c565b602090810291909101810151600084815280835260408082206001600160a01b038e168352909352919091205490915081811015612ade5760405162461bcd60e51b81526004016109da90613f49565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290612b1b908490613bcf565b9250508190555050505080612b2f90613d92565b9050612a53565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612b86929190613ed6565b60405180910390a4610ccd818787878787612e3e565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110612bd657612bd6613d7c565b602090810291909101015292915050565b6001600160a01b0384163b15610ccd5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190612c2b9089908990889088908890600401613f93565b6020604051808303816000875af1925050508015612c66575060408051601f3d908101601f19168201909252612c6391810190613fd8565b60015b612d1257612c72613ff5565b806308c379a003612cab5750612c86614011565b80612c915750612cad565b8060405162461bcd60e51b81526004016109da9190613346565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016109da565b6001600160e01b0319811663f23a6e6160e01b146124df5760405162461bcd60e51b81526004016109da9061409a565b816001600160a01b0316836001600160a01b031603612db55760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016109da565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6000806000612e318585613023565b9150915061127b81613068565b6001600160a01b0384163b15610ccd5760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190612e8290899089908890889088906004016140e2565b6020604051808303816000875af1925050508015612ebd575060408051601f3d908101601f19168201909252612eba91810190613fd8565b60015b612ec957612c72613ff5565b6001600160e01b0319811663bc197c8160e01b146124df5760405162461bcd60e51b81526004016109da9061409a565b6001600160a01b038416612f1f5760405162461bcd60e51b81526004016109da90613f04565b336000612f2b85612b9c565b90506000612f3885612b9c565b90506000868152602081815260408083206001600160a01b038c16845290915290205485811015612f7b5760405162461bcd60e51b81526004016109da90613f49565b6000878152602081815260408083206001600160a01b038d8116855292528083208985039055908a16825281208054889290612fb8908490613bcf565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4613018848a8a8a8a8a612be7565b505050505050505050565b60008082516041036130595760208301516040840151606085015160001a61304d878285856131b2565b94509450505050613061565b506000905060025b9250929050565b600081600481111561307c5761307c614140565b036130845750565b600181600481111561309857613098614140565b036130e55760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109da565b60028160048111156130f9576130f9614140565b036131465760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109da565b600381600481111561315a5761315a614140565b03610d905760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016109da565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156131e9575060009050600361326d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561323d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166132665760006001925092505061326d565b9150600090505b94509492505050565b80356001600160a01b038116811461328d57600080fd5b919050565b600080604083850312156132a557600080fd5b6132ae83613276565b946020939093013593505050565b6001600160e01b031981168114610d9057600080fd5b6000602082840312156132e457600080fd5b81356132ef816132bc565b9392505050565b60005b838110156133115781810151838201526020016132f9565b50506000910152565b600081518084526133328160208601602086016132f6565b601f01601f19169290920160200192915050565b6020815260006132ef602083018461331a565b60006020828403121561336b57600080fd5b5035919050565b60006020828403121561338457600080fd5b6132ef82613276565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b03811182821017156133c8576133c861338d565b6040525050565b60006001600160401b038211156133e8576133e861338d565b5060051b60200190565b600082601f83011261340357600080fd5b81356020613410826133cf565b60405161341d82826133a3565b83815260059390931b850182019282810191508684111561343d57600080fd5b8286015b848110156134585780358352918301918301613441565b509695505050505050565b600082601f83011261347457600080fd5b81356001600160401b0381111561348d5761348d61338d565b6040516134a4601f8301601f1916602001826133a3565b8181528460208386010111156134b957600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156134ee57600080fd5b6134f786613276565b945061350560208701613276565b935060408601356001600160401b038082111561352157600080fd5b61352d89838a016133f2565b9450606088013591508082111561354357600080fd5b61354f89838a016133f2565b9350608088013591508082111561356557600080fd5b5061357288828901613463565b9150509295509295909350565b60008060006060848603121561359457600080fd5b61359d84613276565b95602085013595506040909401359392505050565b8015158114610d9057600080fd5b80356001600160401b038116811461328d57600080fd5b60008060008060008060c087890312156135f057600080fd5b863595506020870135613602816135b2565b9450613610604088016135c0565b935060608701356001600160401b0381111561362b57600080fd5b61363789828a01613463565b9350506080870135915060a087013590509295509295509295565b6000806040838503121561366557600080fd5b82356001600160401b038082111561367c57600080fd5b818501915085601f83011261369057600080fd5b8135602061369d826133cf565b6040516136aa82826133a3565b83815260059390931b85018201928281019150898411156136ca57600080fd5b948201945b838610156136ef576136e086613276565b825294820194908201906136cf565b9650508601359250508082111561370557600080fd5b50613712858286016133f2565b9150509250929050565b600081518084526020808501945080840160005b8381101561374c57815187529582019590820190600101613730565b509495945050505050565b6020815260006132ef602083018461371c565b6000806040838503121561377d57600080fd5b8235915061378d60208401613276565b90509250929050565b861515815260006001600160401b03808816602084015280871660408401525060c060608301526137ca60c083018661331a565b60808301949094525060a00152949350505050565b600080604083850312156137f257600080fd5b50508035926020909101359150565b6000806040838503121561381457600080fd5b8235915061378d602084016135c0565b6000806040838503121561383757600080fd5b8235915060208301356001600160401b0381111561385457600080fd5b61371285828601613463565b6000806020838503121561387357600080fd5b82356001600160401b038082111561388a57600080fd5b818501915085601f83011261389e57600080fd5b8135818111156138ad57600080fd5b8660208260051b85010111156138c257600080fd5b60209290920196919550909350505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561397757888303603f190185528151805115158452878101516001600160401b039081168986015287820151168785015260608082015160c0828701819052919061394c8388018261331a565b6080858101519089015260a094850151949097019390935250505093860193908601906001016138fb565b509098975050505050505050565b6000806040838503121561399857600080fd5b6139a183613276565b915060208301356139b1816135b2565b809150509250929050565b600080600080606085870312156139d257600080fd5b84356001600160401b03808211156139e957600080fd5b818701915087601f8301126139fd57600080fd5b813581811115613a0c57600080fd5b886020828501011115613a1e57600080fd5b6020928301999098509187013596604001359550909350505050565b60008060408385031215613a4d57600080fd5b82356001600160401b0380821115613a6457600080fd5b613a70868387016133f2565b9350602085013591508082111561370557600080fd5b60008060408385031215613a9957600080fd5b8235915060208301356139b1816135b2565b60008060408385031215613abe57600080fd5b613ac783613276565b915061378d60208401613276565b600080600080600060a08688031215613aed57600080fd5b613af686613276565b9450613b0460208701613276565b9350604086013592506060860135915060808601356001600160401b03811115613b2d57600080fd5b61357288828901613463565b600181811c90821680613b4d57607f821691505b602082108103613b6d57634e487b7160e01b600052602260045260246000fd5b50919050565b60008351613b858184602088016132f6565b835190830190613b998183602088016132f6565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a0657610a06613ba2565b80820180821115610a0657610a06613ba2565b6020808252600b908201526a4e6f742062757961626c6560a81b604082015260600190565b6020808252600a9082015269135a5b9d1959081bdd5d60b21b604082015260600190565b6020808252600b908201526a043616e27742062757920360ac1b604082015260600190565b6001600160401b03818116838216019080821115613c7057613c70613ba2565b5092915050565b601f82111561147057600081815260208120601f850160051c81016020861015613c9e5750805b601f850160051c820191505b81811015610ccd57828155600101613caa565b81516001600160401b03811115613cd657613cd661338d565b613cea81613ce48454613b39565b84613c77565b602080601f831160018114613d1f5760008415613d075750858301515b600019600386901b1c1916600185901b178555610ccd565b600085815260208120601f198616915b82811015613d4e57888601518255948401946001909101908401613d2f565b5085821015613d6c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b600060018201613da457613da4613ba2565b5060010190565b60208082526017908201527f546f6b656e20646f65736e277420657869737420796574000000000000000000604082015260600190565b600060208284031215613df457600080fd5b81516132ef816135b2565b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b604081526000613ee9604083018561371c565b8281036020840152613efb818561371c565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090613fcd9083018461331a565b979650505050505050565b600060208284031215613fea57600080fd5b81516132ef816132bc565b600060033d111561400e5760046000803e5060005160e01c5b90565b600060443d101561401f5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561404e57505050505090565b82850191508151818111156140665750505050505090565b843d87010160208285010111156140805750505050505090565b61408f602082860101876133a3565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6001600160a01b0386811682528516602082015260a06040820181905260009061410e9083018661371c565b8281036060840152614120818661371c565b90508281036080840152614134818561331a565b98975050505050505050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220952fc77d636fde4b39c872c4b89c3a0dc46a83e7b60545a11ce93f434fa8672864736f6c63430008120033

Deployed Bytecode

0x6080604052600436106102e35760003560e01c80636d0fd50711610190578063be919dd0116100dc578063e985e9c511610095578063f242432a1161006f578063f242432a14610900578063f2fde38b14610920578063f7eb425014610940578063fc6f94681461095357600080fd5b8063e985e9c514610876578063ecba222a146108bf578063efa492e4146108e057600080fd5b8063be919dd0146107c8578063c0aa4110146107de578063d351cfdc1461080e578063db512e771461082e578063e2b9e1861461084e578063e635d5c11461086357600080fd5b806398764d8311610149578063af17dea611610123578063af17dea614610753578063b0ccc31e14610768578063b7a0816a14610788578063b8d1e532146107a857600080fd5b806398764d83146106e6578063a22cb46514610713578063a2773b111461073357600080fd5b80636d0fd50714610647578063715018a6146106675780637fb3a9a21461067c5780638da5cb5b1461069c5780639169daa1146106b157806395d89b41146106d157600080fd5b80633ab1a4941161024f57806352090713116102085780635965805d116101e25780635965805d146105d25780635ef9432a146105f257806362e8e8ac146106075780636c19e7831461062757600080fd5b8063520907131461055f578063559c2d1b1461057f578063585531b1146105b157600080fd5b80633ab1a494146104b75780633ccfd60b146104d7578063413b9c34146104df57806341bec0d2146104f25780634ce5fb7e146105125780634e1273f41461053257600080fd5b8063205ea1c3116102a1578063205ea1c314610400578063238ac93314610420578063276184ae146104405780632c1e816d146104605780632eb2c2d6146104825780633902e981146104a257600080fd5b8062fdd58e146102e857806301ffc9a71461031b57806306fdde031461034b5780630e89341c1461036d5780631581b6001461038d5780631c129f29146103c5575b600080fd5b3480156102f457600080fd5b50610308610303366004613292565b610973565b6040519081526020015b60405180910390f35b34801561032757600080fd5b5061033b6103363660046132d2565b610a0c565b6040519015158152602001610312565b34801561035757600080fd5b50610360610a5c565b6040516103129190613346565b34801561037957600080fd5b50610360610388366004613359565b610aee565b34801561039957600080fd5b506010546103ad906001600160a01b031681565b6040516001600160a01b039091168152602001610312565b3480156103d157600080fd5b5061033b6103e0366004613292565b600d60209081526000928352604080842090915290825290205460ff1681565b34801561040c57600080fd5b50600f546103ad906001600160a01b031681565b34801561042c57600080fd5b506009546103ad906001600160a01b031681565b34801561044c57600080fd5b506007546103ad906001600160a01b031681565b34801561046c57600080fd5b5061048061047b366004613372565b610c7c565b005b34801561048e57600080fd5b5061048061049d3660046134d6565b610ca6565b3480156104ae57600080fd5b50610480610cd5565b3480156104c357600080fd5b506104806104d2366004613372565b610cfe565b610480610d28565b6104806104ed36600461357f565b610d93565b3480156104fe57600080fd5b5061048061050d366004613372565b610fa0565b34801561051e57600080fd5b5061048061052d3660046135d7565b610fca565b34801561053e57600080fd5b5061055261054d366004613652565b61115a565b6040516103129190613757565b34801561056b57600080fd5b5061048061057a36600461376a565b611283565b34801561058b57600080fd5b5061059f61059a366004613359565b6112e6565b60405161031296959493929190613796565b3480156105bd57600080fd5b50600a5461033b90600160a01b900460ff1681565b3480156105de57600080fd5b506104806105ed3660046137df565b6113b4565b3480156105fe57600080fd5b50610480611475565b34801561061357600080fd5b506104806106223660046137df565b61151a565b34801561063357600080fd5b50610480610642366004613372565b611565565b34801561065357600080fd5b50610480610662366004613801565b61158f565b34801561067357600080fd5b50610480611675565b34801561068857600080fd5b50610480610697366004613824565b611689565b3480156106a857600080fd5b506103ad611719565b3480156106bd57600080fd5b506104806106cc366004613372565b611732565b3480156106dd57600080fd5b5061036061175c565b3480156106f257600080fd5b50610706610701366004613860565b61176b565b60405161031291906138d4565b34801561071f57600080fd5b5061048061072e366004613985565b61193a565b34801561073f57600080fd5b5061048061074e3660046139bc565b61194e565b34801561075f57600080fd5b50610360611ba1565b34801561077457600080fd5b506004546103ad906001600160a01b031681565b34801561079457600080fd5b506104806107a33660046137df565b611c2f565b3480156107b457600080fd5b506104806107c3366004613372565b611c7a565b3480156107d457600080fd5b50610308600e5481565b3480156107ea57600080fd5b5061033b6107f9366004613359565b600b6020526000908152604090205460ff1681565b34801561081a57600080fd5b50610480610829366004613a3a565b611d32565b34801561083a57600080fd5b50610480610849366004613a86565b611d5c565b34801561085a57600080fd5b50610360611db2565b6104806108713660046137df565b611dbf565b34801561088257600080fd5b5061033b610891366004613aab565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b3480156108cb57600080fd5b5060045461033b90600160a01b900460ff1681565b3480156108ec57600080fd5b506104806108fb366004613359565b612001565b34801561090c57600080fd5b5061048061091b366004613ad5565b61200e565b34801561092c57600080fd5b5061048061093b366004613372565b612035565b61048061094e3660046137df565b6120ab565b34801561095f57600080fd5b506008546103ad906001600160a01b031681565b60006001600160a01b0383166109e35760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b506000818152602081815260408083206001600160a01b03861684529091529020545b92915050565b60006001600160e01b03198216636cdb3d1360e11b1480610a3d57506001600160e01b031982166303a24d0760e21b145b80610a0657506301ffc9a760e01b6001600160e01b0319831614610a06565b606060058054610a6b90613b39565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9790613b39565b8015610ae45780601f10610ab957610100808354040283529160200191610ae4565b820191906000526020600020905b815481529060010190602001808311610ac757829003601f168201915b5050505050905090565b6000818152600b602052604090205460609060ff16610b4f5760405162461bcd60e51b815260206004820152601e60248201527f5552492072657175657374656420666f7220696e76616c69642074797065000060448201526064016109da565b6000828152600c60209081526040808320815160c081018352815460ff8116151582526001600160401b036101008204811695830195909552600160481b900490931691830191909152600181018054606084019190610bae90613b39565b80601f0160208091040260200160405190810160405280929190818152602001828054610bda90613b39565b8015610c275780601f10610bfc57610100808354040283529160200191610c27565b820191906000526020600020905b815481529060010190602001808311610c0a57829003601f168201915b505050505081526020016002820154815260200160038201548152505090508060600151610c548461220f565b604051602001610c65929190613b73565b604051602081830303815290604052915050919050565b610c846122a1565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b846001600160a01b0381163314610cc057610cc033612300565b610ccd86868686866123c2565b505050505050565b610cdd6122a1565b600a805460ff60a01b198116600160a01b9182900460ff1615909102179055565b610d066122a1565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b610d306122a1565b6010546040516000916001600160a01b03169047908381818185875af1925050503d8060008114610d7d576040519150601f19603f3d011682016040523d82523d6000602084013e610d82565b606091505b5050905080610d9057600080fd5b50565b6000828152600c60205260409020600a546001600160a01b03163314610dec5760405162461bcd60e51b815260206004820152600e60248201526d43726f73736d696e74206f6e6c7960901b60448201526064016109da565b6000816002015411610e355760405162461bcd60e51b8152602060048201526012602482015271086c2dc4ee840c4eaf240eed2e8d0408aa8960731b60448201526064016109da565b81600e54610e439190613bb8565b828260020154610e539190613bb8565b610e5d9190613bcf565b341015610e9d5760405162461bcd60e51b815260206004820152600e60248201526d09cdee840cadcdeeaced040cae8d60931b60448201526064016109da565b805460ff16610ebe5760405162461bcd60e51b81526004016109da90613be2565b80546001600160401b036101008204811691610ee3918591600160481b900416613bcf565b1115610f015760405162461bcd60e51b81526004016109da90613c07565b60008211610f215760405162461bcd60e51b81526004016109da90613c2b565b805482908290600990610f45908490600160481b90046001600160401b0316613c50565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610f848484846040518060200160405280600081525061240e565b610f9a82600e54610f959190613bb8565b6124e8565b50505050565b610fa86122a1565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b610fd26122a1565b6000868152600b602052604090205460ff16156110315760405162461bcd60e51b815260206004820152601860248201527f746f6b656e205f696420616c726561647920657869737473000000000000000060448201526064016109da565b6000868152600b602090815260408083208054600160ff199091168117909155815160c08101835289151581526001600160401b03898116828601908152828501878152606084018b8152608085018b905260a085018a90528e8952600c90975294909620825181549751955168ffffffffffffffffff1990981690151568ffffffffffffffff00191617610100958316959095029490941770ffffffffffffffff0000000000000000001916600160481b9690911695909502949094178255915190918201906111029082613cbd565b506080820151816002015560a08201518160030155905050857f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b8460405161114a9190613346565b60405180910390a2505050505050565b606081518351146111bf5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016109da565b600083516001600160401b038111156111da576111da61338d565b604051908082528060200260200182016040528015611203578160200160208202803683370190505b50905060005b845181101561127b5761124e85828151811061122757611227613d7c565b602002602001015185838151811061124157611241613d7c565b6020026020010151610973565b82828151811061126057611260613d7c565b602090810291909101015261127481613d92565b9050611209565b509392505050565b6008546001600160a01b031633146112d65760405162461bcd60e51b8152602060048201526016602482015275496e76616c6964206275726e6572206164647265737360501b60448201526064016109da565b6112e281836001612548565b5050565b600c602052600090815260409020805460018201805460ff8316936001600160401b036101008504811694600160481b90041692909161132590613b39565b80601f016020809104026020016040519081016040528092919081815260200182805461135190613b39565b801561139e5780601f106113735761010080835404028352916020019161139e565b820191906000526020600020905b81548152906001019060200180831161138157829003601f168201915b5050505050908060020154908060030154905086565b6113bc6122a1565b6000828152600c6020526040902080546001600160401b0361010082048116916113ef918591600160481b900416613bcf565b111561140d5760405162461bcd60e51b81526004016109da90613c07565b805482908290600990611431908490600160481b90046001600160401b0316613c50565b92506101000a8154816001600160401b0302191690836001600160401b031602179055506114703384846040518060200160405280600081525061240e565b505050565b61147d611719565b6001600160a01b0316336001600160a01b0316146114ae57604051635fc483c560e01b815260040160405180910390fd5b600454600160a01b900460ff16156114d957604051631551a48f60e11b815260040160405180910390fd5b600480546001600160a81b031916600160a01b1790556040517f51e2d870cc2e10853e38dc06fcdae46ad3c3f588f326608803dac6204541ad1690600090a1565b6115226122a1565b6000828152600b602052604090205460ff166115505760405162461bcd60e51b81526004016109da90613dab565b6000918252600c602052604090912060020155565b61156d6122a1565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6115976122a1565b6000828152600b602052604090205460ff166115c55760405162461bcd60e51b81526004016109da90613dab565b6000828152600c6020526040902080546001600160401b036101009091048116908316101561164d5760405162461bcd60e51b815260206004820152602e60248201527f4e657720737570706c79206d7573742062652067726561746572207468616e2060448201526d63757272656e7420737570706c7960901b60648201526084016109da565b80546001600160401b039092166101000268ffffffffffffffff001990921691909117905550565b61167d6122a1565b61168760006126c4565b565b6116916122a1565b6000828152600b602052604090205460ff166116bf5760405162461bcd60e51b81526004016109da90613dab565b6000828152600c60205260409020600181016116db8382613cbd565b50827f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b8360405161170c9190613346565b60405180910390a2505050565b600061172d6003546001600160a01b031690565b905090565b61173a6122a1565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b606060068054610a6b90613b39565b60606000826001600160401b038111156117875761178761338d565b6040519080825280602002602001820160405280156117e657816020015b6040805160c081018252600080825260208083018290529282018190526060808301526080820181905260a082015282526000199092019101816117a55790505b50905060005b8381101561127b57600c600086868481811061180a5761180a613d7c565b60209081029290920135835250818101929092526040908101600020815160c081018352815460ff8116151582526001600160401b036101008204811695830195909552600160481b90049093169183019190915260018101805460608401919061187490613b39565b80601f01602080910402602001604051908101604052809291908181526020018280546118a090613b39565b80156118ed5780601f106118c2576101008083540402835291602001916118ed565b820191906000526020600020905b8154815290600101906020018083116118d057829003601f168201915b505050505081526020016002820154815260200160038201548152505082828151811061191c5761191c613d7c565b6020026020010181905250808061193290613d92565b9150506117ec565b8161194481612300565b6114708383612716565b6000828152600c60205260409020600a54600160a01b900460ff166119ae5760405162461bcd60e51b815260206004820152601660248201527520b63637bbb634b9ba1031b630b4b69034b99037b33360511b60448201526064016109da565b80546001600160401b0361010082048116916119d3918591600160481b900416613bcf565b11156119f15760405162461bcd60e51b81526004016109da90613c07565b336000908152600d6020908152604080832086845290915290205460ff1615611a4d5760405162461bcd60e51b815260206004820152600e60248201526d105b1c9958591e481b5a5b9d195960921b60448201526064016109da565b336000818152600d602090815260408083208784528252808320805460ff191660011790555160609390931b6bffffffffffffffffffffffff19169083015260348201859052605482018490529060740160408051601f198184030181528282528051602091820120600954601f8a018390048302850183019093528884529350611b00926001600160a01b039092169184918a908a908190840183828082843760009201919091525061272192505050565b611b3e5760405162461bcd60e51b815260206004820152600f60248201526e24b73b30b634b2103b37bab1b432b960891b60448201526064016109da565b815483908390600990611b62908490600160481b90046001600160401b0316613c50565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550610ccd3385856040518060200160405280600081525061240e565b60068054611bae90613b39565b80601f0160208091040260200160405190810160405280929190818152602001828054611bda90613b39565b8015611c275780601f10611bfc57610100808354040283529160200191611c27565b820191906000526020600020905b815481529060010190602001808311611c0a57829003601f168201915b505050505081565b611c376122a1565b6000828152600b602052604090205460ff16611c655760405162461bcd60e51b81526004016109da90613dab565b6000918252600c602052604090912060030155565b611c82611719565b6001600160a01b0316336001600160a01b031614611cb357604051635fc483c560e01b815260040160405180910390fd5b600454600160a01b900460ff1615611cde57604051631551a48f60e11b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f9f513fe86dc42fdbac355fa4d9b1d5be7b5e6cd2df67e30db8003766568de4769060200160405180910390a150565b611d3a6122a1565b6112e2611d45611719565b8383604051806020016040528060008152506127a0565b611d646122a1565b6000828152600b602052604090205460ff16611d925760405162461bcd60e51b81526004016109da90613dab565b6000918252600c6020526040909120805460ff1916911515919091179055565b60058054611bae90613b39565b6000828152600c602052604090206003810154611e155760405162461bcd60e51b8152602060048201526014602482015273043616e27742062757920776974682045524332360641b60448201526064016109da565b80546001600160401b036101008204811691611e3a918591600160481b900416613bcf565b1115611e585760405162461bcd60e51b81526004016109da90613c07565b805460ff16611e795760405162461bcd60e51b81526004016109da90613be2565b60008211611e995760405162461bcd60e51b81526004016109da90613c2b565b81600e54611ea79190613bb8565b341015611ee75760405162461bcd60e51b815260206004820152600e60248201526d4e6f207061796d656e742066656560901b60448201526064016109da565b60075460105460038301546001600160a01b03928316926323b872dd923392911690611f14908790613bb8565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064016020604051808303816000875af1158015611f68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8c9190613de2565b50805482908290600990611fb1908490600160481b90046001600160401b0316613c50565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550611ff03384846040518060200160405280600081525061240e565b61147082600e54610f959190613bb8565b6120096122a1565b600e55565b846001600160a01b03811633146120285761202833612300565b610ccd86868686866128eb565b61203d6122a1565b6001600160a01b0381166120a25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109da565b610d90816126c4565b6000828152600c6020526040902060028101546120ff5760405162461bcd60e51b8152602060048201526012602482015271086c2dc4ee840c4eaf240eed2e8d0408aa8960731b60448201526064016109da565b81600e5461210d9190613bb8565b82826002015461211d9190613bb8565b6121279190613bcf565b3410156121675760405162461bcd60e51b815260206004820152600e60248201526d09cdee840cadcdeeaced040cae8d60931b60448201526064016109da565b805460ff166121885760405162461bcd60e51b81526004016109da90613be2565b80546001600160401b0361010082048116916121ad918591600160481b900416613bcf565b11156121cb5760405162461bcd60e51b81526004016109da90613c07565b600082116121eb5760405162461bcd60e51b81526004016109da90613c2b565b805482908290600990611fb1908490600160481b90046001600160401b0316613c50565b6060600061221c83612930565b60010190506000816001600160401b0381111561223b5761223b61338d565b6040519080825280601f01601f191660200182016040528015612265576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461226f57509392505050565b336122aa611719565b6001600160a01b0316146116875760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109da565b6004546001600160a01b0316801580159061232557506000816001600160a01b03163b115b156112e257604051633185c44d60e21b81523060048201526001600160a01b03838116602483015282169063c617113490604401602060405180830381865afa158015612376573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239a9190613de2565b6112e257604051633b79c77360e21b81526001600160a01b03831660048201526024016109da565b6001600160a01b0385163314806123de57506123de8533610891565b6123fa5760405162461bcd60e51b81526004016109da90613dff565b6124078585858585612a08565b5050505050565b6001600160a01b0384166124345760405162461bcd60e51b81526004016109da90613e4d565b33600061244085612b9c565b9050600061244d85612b9c565b90506000868152602081815260408083206001600160a01b038b1684529091528120805487929061247f908490613bcf565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46124df83600089898989612be7565b50505050505050565b600f546040516000916001600160a01b03169083908381818185875af1925050503d8060008114612535576040519150601f19603f3d011682016040523d82523d6000602084013e61253a565b606091505b50509050806112e257600080fd5b6001600160a01b0383166125aa5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b60648201526084016109da565b3360006125b684612b9c565b905060006125c384612b9c565b60408051602080820183526000918290528882528181528282206001600160a01b038b168352905220549091508481101561264c5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b60648201526084016109da565b6000868152602081815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46040805160208101909152600090526124df565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6112e2338383612d42565b600061278361277d846040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b83612e22565b6001600160a01b0316846001600160a01b03161490509392505050565b6001600160a01b0384166127c65760405162461bcd60e51b81526004016109da90613e4d565b81518351146127e75760405162461bcd60e51b81526004016109da90613e8e565b3360005b84518110156128835783818151811061280657612806613d7c565b602002602001015160008087848151811061282357612823613d7c565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b03168152602001908152602001600020600082825461286b9190613bcf565b9091555081905061287b81613d92565b9150506127eb565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516128d4929190613ed6565b60405180910390a461240781600087878787612e3e565b6001600160a01b03851633148061290757506129078533610891565b6129235760405162461bcd60e51b81526004016109da90613dff565b6124078585858585612ef9565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061296f5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061299b576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106129b957662386f26fc10000830492506010015b6305f5e10083106129d1576305f5e100830492506008015b61271083106129e557612710830492506004015b606483106129f7576064830492506002015b600a8310610a065760010192915050565b8151835114612a295760405162461bcd60e51b81526004016109da90613e8e565b6001600160a01b038416612a4f5760405162461bcd60e51b81526004016109da90613f04565b3360005b8451811015612b36576000858281518110612a7057612a70613d7c565b602002602001015190506000858381518110612a8e57612a8e613d7c565b602090810291909101810151600084815280835260408082206001600160a01b038e168352909352919091205490915081811015612ade5760405162461bcd60e51b81526004016109da90613f49565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290612b1b908490613bcf565b9250508190555050505080612b2f90613d92565b9050612a53565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612b86929190613ed6565b60405180910390a4610ccd818787878787612e3e565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110612bd657612bd6613d7c565b602090810291909101015292915050565b6001600160a01b0384163b15610ccd5760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190612c2b9089908990889088908890600401613f93565b6020604051808303816000875af1925050508015612c66575060408051601f3d908101601f19168201909252612c6391810190613fd8565b60015b612d1257612c72613ff5565b806308c379a003612cab5750612c86614011565b80612c915750612cad565b8060405162461bcd60e51b81526004016109da9190613346565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016109da565b6001600160e01b0319811663f23a6e6160e01b146124df5760405162461bcd60e51b81526004016109da9061409a565b816001600160a01b0316836001600160a01b031603612db55760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016109da565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6000806000612e318585613023565b9150915061127b81613068565b6001600160a01b0384163b15610ccd5760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190612e8290899089908890889088906004016140e2565b6020604051808303816000875af1925050508015612ebd575060408051601f3d908101601f19168201909252612eba91810190613fd8565b60015b612ec957612c72613ff5565b6001600160e01b0319811663bc197c8160e01b146124df5760405162461bcd60e51b81526004016109da9061409a565b6001600160a01b038416612f1f5760405162461bcd60e51b81526004016109da90613f04565b336000612f2b85612b9c565b90506000612f3885612b9c565b90506000868152602081815260408083206001600160a01b038c16845290915290205485811015612f7b5760405162461bcd60e51b81526004016109da90613f49565b6000878152602081815260408083206001600160a01b038d8116855292528083208985039055908a16825281208054889290612fb8908490613bcf565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4613018848a8a8a8a8a612be7565b505050505050505050565b60008082516041036130595760208301516040840151606085015160001a61304d878285856131b2565b94509450505050613061565b506000905060025b9250929050565b600081600481111561307c5761307c614140565b036130845750565b600181600481111561309857613098614140565b036130e55760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109da565b60028160048111156130f9576130f9614140565b036131465760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109da565b600381600481111561315a5761315a614140565b03610d905760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016109da565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156131e9575060009050600361326d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561323d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166132665760006001925092505061326d565b9150600090505b94509492505050565b80356001600160a01b038116811461328d57600080fd5b919050565b600080604083850312156132a557600080fd5b6132ae83613276565b946020939093013593505050565b6001600160e01b031981168114610d9057600080fd5b6000602082840312156132e457600080fd5b81356132ef816132bc565b9392505050565b60005b838110156133115781810151838201526020016132f9565b50506000910152565b600081518084526133328160208601602086016132f6565b601f01601f19169290920160200192915050565b6020815260006132ef602083018461331a565b60006020828403121561336b57600080fd5b5035919050565b60006020828403121561338457600080fd5b6132ef82613276565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b03811182821017156133c8576133c861338d565b6040525050565b60006001600160401b038211156133e8576133e861338d565b5060051b60200190565b600082601f83011261340357600080fd5b81356020613410826133cf565b60405161341d82826133a3565b83815260059390931b850182019282810191508684111561343d57600080fd5b8286015b848110156134585780358352918301918301613441565b509695505050505050565b600082601f83011261347457600080fd5b81356001600160401b0381111561348d5761348d61338d565b6040516134a4601f8301601f1916602001826133a3565b8181528460208386010111156134b957600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a086880312156134ee57600080fd5b6134f786613276565b945061350560208701613276565b935060408601356001600160401b038082111561352157600080fd5b61352d89838a016133f2565b9450606088013591508082111561354357600080fd5b61354f89838a016133f2565b9350608088013591508082111561356557600080fd5b5061357288828901613463565b9150509295509295909350565b60008060006060848603121561359457600080fd5b61359d84613276565b95602085013595506040909401359392505050565b8015158114610d9057600080fd5b80356001600160401b038116811461328d57600080fd5b60008060008060008060c087890312156135f057600080fd5b863595506020870135613602816135b2565b9450613610604088016135c0565b935060608701356001600160401b0381111561362b57600080fd5b61363789828a01613463565b9350506080870135915060a087013590509295509295509295565b6000806040838503121561366557600080fd5b82356001600160401b038082111561367c57600080fd5b818501915085601f83011261369057600080fd5b8135602061369d826133cf565b6040516136aa82826133a3565b83815260059390931b85018201928281019150898411156136ca57600080fd5b948201945b838610156136ef576136e086613276565b825294820194908201906136cf565b9650508601359250508082111561370557600080fd5b50613712858286016133f2565b9150509250929050565b600081518084526020808501945080840160005b8381101561374c57815187529582019590820190600101613730565b509495945050505050565b6020815260006132ef602083018461371c565b6000806040838503121561377d57600080fd5b8235915061378d60208401613276565b90509250929050565b861515815260006001600160401b03808816602084015280871660408401525060c060608301526137ca60c083018661331a565b60808301949094525060a00152949350505050565b600080604083850312156137f257600080fd5b50508035926020909101359150565b6000806040838503121561381457600080fd5b8235915061378d602084016135c0565b6000806040838503121561383757600080fd5b8235915060208301356001600160401b0381111561385457600080fd5b61371285828601613463565b6000806020838503121561387357600080fd5b82356001600160401b038082111561388a57600080fd5b818501915085601f83011261389e57600080fd5b8135818111156138ad57600080fd5b8660208260051b85010111156138c257600080fd5b60209290920196919550909350505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561397757888303603f190185528151805115158452878101516001600160401b039081168986015287820151168785015260608082015160c0828701819052919061394c8388018261331a565b6080858101519089015260a094850151949097019390935250505093860193908601906001016138fb565b509098975050505050505050565b6000806040838503121561399857600080fd5b6139a183613276565b915060208301356139b1816135b2565b809150509250929050565b600080600080606085870312156139d257600080fd5b84356001600160401b03808211156139e957600080fd5b818701915087601f8301126139fd57600080fd5b813581811115613a0c57600080fd5b886020828501011115613a1e57600080fd5b6020928301999098509187013596604001359550909350505050565b60008060408385031215613a4d57600080fd5b82356001600160401b0380821115613a6457600080fd5b613a70868387016133f2565b9350602085013591508082111561370557600080fd5b60008060408385031215613a9957600080fd5b8235915060208301356139b1816135b2565b60008060408385031215613abe57600080fd5b613ac783613276565b915061378d60208401613276565b600080600080600060a08688031215613aed57600080fd5b613af686613276565b9450613b0460208701613276565b9350604086013592506060860135915060808601356001600160401b03811115613b2d57600080fd5b61357288828901613463565b600181811c90821680613b4d57607f821691505b602082108103613b6d57634e487b7160e01b600052602260045260246000fd5b50919050565b60008351613b858184602088016132f6565b835190830190613b998183602088016132f6565b01949350505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a0657610a06613ba2565b80820180821115610a0657610a06613ba2565b6020808252600b908201526a4e6f742062757961626c6560a81b604082015260600190565b6020808252600a9082015269135a5b9d1959081bdd5d60b21b604082015260600190565b6020808252600b908201526a043616e27742062757920360ac1b604082015260600190565b6001600160401b03818116838216019080821115613c7057613c70613ba2565b5092915050565b601f82111561147057600081815260208120601f850160051c81016020861015613c9e5750805b601f850160051c820191505b81811015610ccd57828155600101613caa565b81516001600160401b03811115613cd657613cd661338d565b613cea81613ce48454613b39565b84613c77565b602080601f831160018114613d1f5760008415613d075750858301515b600019600386901b1c1916600185901b178555610ccd565b600085815260208120601f198616915b82811015613d4e57888601518255948401946001909101908401613d2f565b5085821015613d6c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b600060018201613da457613da4613ba2565b5060010190565b60208082526017908201527f546f6b656e20646f65736e277420657869737420796574000000000000000000604082015260600190565b600060208284031215613df457600080fd5b81516132ef816135b2565b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b604081526000613ee9604083018561371c565b8281036020840152613efb818561371c565b95945050505050565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090613fcd9083018461331a565b979650505050505050565b600060208284031215613fea57600080fd5b81516132ef816132bc565b600060033d111561400e5760046000803e5060005160e01c5b90565b600060443d101561401f5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561404e57505050505090565b82850191508151818111156140665750505050505090565b843d87010160208285010111156140805750505050505090565b61408f602082860101876133a3565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6001600160a01b0386811682528516602082015260a06040820181905260009061410e9083018661371c565b8281036060840152614120818661371c565b90508281036080840152614134818561331a565b98975050505050505050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220952fc77d636fde4b39c872c4b89c3a0dc46a83e7b60545a11ce93f434fa8672864736f6c63430008120033

Deployed Bytecode Sourcemap

87018:9732:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71351:230;;;;;;;;;;-1:-1:-1;71351:230:0;;;;;:::i;:::-;;:::i;:::-;;;597:25:1;;;585:2;570:18;71351:230:0;;;;;;;;70374:310;;;;;;;;;;-1:-1:-1;70374:310:0;;;;;:::i;:::-;;:::i;:::-;;;1184:14:1;;1177:22;1159:41;;1147:2;1132:18;70374:310:0;1019:187:1;95316:83:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;95018:290::-;;;;;;;;;;-1:-1:-1;95018:290:0;;;;;:::i;:::-;;:::i;87925:75::-;;;;;;;;;;-1:-1:-1;87925:75:0;;;;-1:-1:-1;;;;;87925:75:0;;;;;;-1:-1:-1;;;;;2316:32:1;;;2298:51;;2286:2;2271:18;87925:75:0;2152:203:1;87713:67:0;;;;;;;;;;-1:-1:-1;87713:67:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;87841:77;;;;;;;;;;-1:-1:-1;87841:77:0;;;;-1:-1:-1;;;;;87841:77:0;;;87224:66;;;;;;;;;;-1:-1:-1;87224:66:0;;;;-1:-1:-1;;;;;87224:66:0;;;87156:27;;;;;;;;;;-1:-1:-1;87156:27:0;;;;-1:-1:-1;;;;;87156:27:0;;;93789:114;;;;;;;;;;-1:-1:-1;93789:114:0;;;;;:::i;:::-;;:::i;:::-;;96302:302;;;;;;;;;;-1:-1:-1;96302:302:0;;;;;:::i;:::-;;:::i;94467:119::-;;;;;;;;;;;;;:::i;94227:110::-;;;;;;;;;;-1:-1:-1;94227:110:0;;;;;:::i;:::-;;:::i;95676:174::-;;;:::i;91790:722::-;;;;;;:::i;:::-;;:::i;93667:114::-;;;;;;;;;;-1:-1:-1;93667:114:0;;;;;:::i;:::-;;:::i;88128:577::-;;;;;;;;;;-1:-1:-1;88128:577:0;;;;;:::i;:::-;;:::i;71747:524::-;;;;;;;;;;-1:-1:-1;71747:524:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;93481:178::-;;;;;;;;;;-1:-1:-1;93481:178:0;;;;;:::i;:::-;;:::i;87654:50::-;;;;;;;;;;-1:-1:-1;87654:50:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;:::i;87376:42::-;;;;;;;;;;-1:-1:-1;87376:42:0;;;;-1:-1:-1;;;87376:42:0;;;;;;90104:321;;;;;;;;;;-1:-1:-1;90104:321:0;;;;;:::i;:::-;;:::i;18695:531::-;;;;;;;;;;;;;:::i;89242:240::-;;;;;;;;;;-1:-1:-1;89242:240:0;;;;;:::i;:::-;;:::i;94129:90::-;;;;;;;;;;-1:-1:-1;94129:90:0;;;;;:::i;:::-;;:::i;89748:348::-;;;;;;;;;;-1:-1:-1;89748:348:0;;;;;:::i;:::-;;:::i;49628:103::-;;;;;;;;;;;;;:::i;88713:270::-;;;;;;;;;;-1:-1:-1;88713:270:0;;;;;:::i;:::-;;:::i;96612:133::-;;;;;;;;;;;;;:::i;94345:114::-;;;;;;;;;;-1:-1:-1;94345:114:0;;;;;:::i;:::-;;:::i;95407:87::-;;;;;;;;;;;;;:::i;94700:310::-;;;;;;;;;;-1:-1:-1;94700:310:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;95858:176::-;;;;;;;;;;-1:-1:-1;95858:176:0;;;;;:::i;:::-;;:::i;90433:699::-;;;;;;;;;;-1:-1:-1;90433:699:0;;;;;:::i;:::-;;:::i;87125:21::-;;;;;;;;;;;;;:::i;12724:53::-;;;;;;;;;;-1:-1:-1;12724:53:0;;;;-1:-1:-1;;;;;12724:53:0;;;89490:250;;;;;;;;;;-1:-1:-1;89490:250:0;;;;;:::i;:::-;;:::i;18082:487::-;;;;;;;;;;-1:-1:-1;18082:487:0;;;;;:::i;:::-;;:::i;87789:45::-;;;;;;;;;;;;;;;;87605:42;;;;;;;;;;-1:-1:-1;87605:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;93300:173;;;;;;;;;;-1:-1:-1;93300:173:0;;;;;:::i;:::-;;:::i;88991:243::-;;;;;;;;;;-1:-1:-1;88991:243:0;;;;;:::i;:::-;;:::i;87099:19::-;;;;;;;;;;;;;:::i;92520:772::-;;;;;;:::i;:::-;;:::i;72571:168::-;;;;;;;;;;-1:-1:-1;72571:168:0;;;;;:::i;:::-;-1:-1:-1;;;;;72694:27:0;;;72670:4;72694:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;72571:168;17308:43;;;;;;;;;;-1:-1:-1;17308:43:0;;;;-1:-1:-1;;;17308:43:0;;;;;;94594:98;;;;;;;;;;-1:-1:-1;94594:98:0;;;;;:::i;:::-;;:::i;96042:252::-;;;;;;;;;;-1:-1:-1;96042:252:0;;;;;:::i;:::-;;:::i;49886:201::-;;;;;;;;;;-1:-1:-1;49886:201:0;;;;;:::i;:::-;;:::i;91140:642::-;;;;;;:::i;:::-;;:::i;87190:27::-;;;;;;;;;;-1:-1:-1;87190:27:0;;;;-1:-1:-1;;;;;87190:27:0;;;71351:230;71437:7;-1:-1:-1;;;;;71465:21:0;;71457:76;;;;-1:-1:-1;;;71457:76:0;;15883:2:1;71457:76:0;;;15865:21:1;15922:2;15902:18;;;15895:30;15961:34;15941:18;;;15934:62;-1:-1:-1;;;16012:18:1;;;16005:40;16062:19;;71457:76:0;;;;;;;;;-1:-1:-1;71551:9:0;:13;;;;;;;;;;;-1:-1:-1;;;;;71551:22:0;;;;;;;;;;71351:230;;;;;:::o;70374:310::-;70476:4;-1:-1:-1;;;;;;70513:41:0;;-1:-1:-1;;;70513:41:0;;:110;;-1:-1:-1;;;;;;;70571:52:0;;-1:-1:-1;;;70571:52:0;70513:110;:163;;;-1:-1:-1;;;;;;;;;;61764:40:0;;;70640:36;61655:157;95316:83;95353:13;95386:5;95379:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95316:83;:::o;95018:290::-;95108:15;;;;:10;:15;;;;;;95074:13;;95108:15;;95100:58;;;;-1:-1:-1;;;95100:58:0;;16679:2:1;95100:58:0;;;16661:21:1;16718:2;16698:18;;;16691:30;16757:32;16737:18;;;16730:60;16807:18;;95100:58:0;16477:354:1;95100:58:0;95171:26;95200:18;;;:13;:18;;;;;;;;95171:47;;;;;;;;;;;;;;;;-1:-1:-1;;;;;95171:47:0;;;;;;;;;;;;-1:-1:-1;;;95171:47:0;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95262:9;:13;;;95277:21;95294:3;95277:16;:21::i;:::-;95245:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95231:69;;;95018:290;;;:::o;93789:114::-;48866:13;:11;:13::i;:::-;93867:12:::1;:28:::0;;-1:-1:-1;;;;;;93867:28:0::1;-1:-1:-1::0;;;;;93867:28:0;;;::::1;::::0;;;::::1;::::0;;93789:114::o;96302:302::-;96522:4;-1:-1:-1;;;;;14222:18:0;;14230:10;14222:18;14218:83;;14257:32;14278:10;14257:20;:32::i;:::-;96539:57:::1;96567:4;96573:2;96577:3;96582:7;96591:4;96539:27;:57::i;:::-;96302:302:::0;;;;;;:::o;94467:119::-;48866:13;:11;:13::i;:::-;94556:22:::1;::::0;;-1:-1:-1;;;;94530:48:0;::::1;-1:-1:-1::0;;;94556:22:0;;;::::1;;;94555:23;94530:48:::0;;::::1;;::::0;;94467:119::o;94227:110::-;48866:13;:11;:13::i;:::-;94303:15:::1;:26:::0;;-1:-1:-1;;;;;;94303:26:0::1;-1:-1:-1::0;;;;;94303:26:0;;;::::1;::::0;;;::::1;::::0;;94227:110::o;95676:174::-;48866:13;:11;:13::i;:::-;95759:15:::1;::::0;95751:64:::1;::::0;95733:12:::1;::::0;-1:-1:-1;;;;;95759:15:0::1;::::0;95789:21:::1;::::0;95733:12;95751:64;95733:12;95751:64;95789:21;95759:15;95751:64:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95732:83;;;95834:7;95826:16;;;::::0;::::1;;95721:129;95676:174::o:0;91790:722::-;91895:27;91925:18;;;:13;:18;;;;;91978:9;;-1:-1:-1;;;;;91978:9:0;91964:10;:23;91956:50;;;;-1:-1:-1;;;91956:50:0;;17749:2:1;91956:50:0;;;17731:21:1;17788:2;17768:18;;;17761:30;-1:-1:-1;;;17807:18:1;;;17800:44;17861:18;;91956:50:0;17547:338:1;91956:50:0;92043:1;92025:9;:15;;;:19;92017:50;;;;-1:-1:-1;;;92017:50:0;;18092:2:1;92017:50:0;;;18074:21:1;18131:2;18111:18;;;18104:30;-1:-1:-1;;;18150:18:1;;;18143:48;18208:18;;92017:50:0;17890:342:1;92017:50:0;92149:7;92131:15;;:25;;;;:::i;:::-;92119:7;92101:9;:15;;;:25;;;;:::i;:::-;92100:57;;;;:::i;:::-;92086:9;:72;;92078:99;;;;-1:-1:-1;;;92078:99:0;;18874:2:1;92078:99:0;;;18856:21:1;18913:2;18893:18;;;18886:30;-1:-1:-1;;;18932:18:1;;;18925:44;18986:18;;92078:99:0;18672:338:1;92078:99:0;92196:17;;;;92188:41;;;;-1:-1:-1;;;92188:41:0;;;;;;;:::i;:::-;92280:16;;-1:-1:-1;;;;;92280:16:0;;;;;;92250:26;;92269:7;;-1:-1:-1;;;92250:16:0;;;:26;:::i;:::-;:46;;92242:69;;;;-1:-1:-1;;;92242:69:0;;;;;;;:::i;:::-;92340:1;92330:7;:11;92322:35;;;;-1:-1:-1;;;92322:35:0;;;;;;;:::i;:::-;92370;;92397:7;;92370:35;;:16;;:35;;92397:7;;-1:-1:-1;;;92370:35:0;;-1:-1:-1;;;;;92370:35:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;92370:35:0;;;;;-1:-1:-1;;;;;92370:35:0;;;;;;92418:31;92424:6;92432:3;92437:7;92418:31;;;;;;;;;;;;:5;:31::i;:::-;92462:42;92496:7;92478:15;;:25;;;;:::i;:::-;92462:15;:42::i;:::-;91884:628;91790:722;;;:::o;93667:114::-;48866:13;:11;:13::i;:::-;93745:12:::1;:28:::0;;-1:-1:-1;;;;;;93745:28:0::1;-1:-1:-1::0;;;;;93745:28:0;;;::::1;::::0;;;::::1;::::0;;93667:114::o;88128:577::-;48866:13;:11;:13::i;:::-;88347:15:::1;::::0;;;:10:::1;:15;::::0;;;;;::::1;;:24;88339:61;;;::::0;-1:-1:-1;;;88339:61:0;;20421:2:1;88339:61:0::1;::::0;::::1;20403:21:1::0;20460:2;20440:18;;;20433:30;20499:26;20479:18;;;20472:54;20543:18;;88339:61:0::1;20219:348:1::0;88339:61:0::1;88411:15;::::0;;;:10:::1;:15;::::0;;;;;;;:22;;88429:4:::1;-1:-1:-1::0;;88411:22:0;;::::1;::::0;::::1;::::0;;;88467:198;;::::1;::::0;::::1;::::0;;;::::1;;::::0;;-1:-1:-1;;;;;88467:198:0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;88446:18;;;:13:::1;:18:::0;;;;;;;:219;;;;;;;;-1:-1:-1;;88446:219:0;;;;::::1;;-1:-1:-1::0;;88446:219:0;;88411:22:::1;88446:219:::0;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;88446:219:0::1;-1:-1:-1::0;;;88446:219:0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;;:18;;:219;::::1;::::0;::::1;::::0;;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;88693:3;88683:14;88687:4;88683:14;;;;;;:::i;:::-;;;;;;;;88128:577:::0;;;;;;:::o;71747:524::-;71903:16;71964:3;:10;71945:8;:15;:29;71937:83;;;;-1:-1:-1;;;71937:83:0;;22978:2:1;71937:83:0;;;22960:21:1;23017:2;22997:18;;;22990:30;23056:34;23036:18;;;23029:62;-1:-1:-1;;;23107:18:1;;;23100:39;23156:19;;71937:83:0;22776:405:1;71937:83:0;72033:30;72080:8;:15;-1:-1:-1;;;;;72066:30:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72066:30:0;;72033:63;;72114:9;72109:122;72133:8;:15;72129:1;:19;72109:122;;;72189:30;72199:8;72208:1;72199:11;;;;;;;;:::i;:::-;;;;;;;72212:3;72216:1;72212:6;;;;;;;;:::i;:::-;;;;;;;72189:9;:30::i;:::-;72170:13;72184:1;72170:16;;;;;;;;:::i;:::-;;;;;;;;;;:49;72150:3;;;:::i;:::-;;;72109:122;;;-1:-1:-1;72250:13:0;71747:524;-1:-1:-1;;;71747:524:0:o;93481:178::-;93578:12;;-1:-1:-1;;;;;93578:12:0;93564:10;:26;93556:61;;;;-1:-1:-1;;;93556:61:0;;23660:2:1;93556:61:0;;;23642:21:1;23699:2;23679:18;;;23672:30;-1:-1:-1;;;23718:18:1;;;23711:52;23780:18;;93556:61:0;23458:346:1;93556:61:0;93628:23;93634:8;93644:3;93649:1;93628:5;:23::i;:::-;93481:178;;:::o;87654:50::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;87654:50:0;;;;;;-1:-1:-1;;;87654:50:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;90104:321::-;48866:13;:11;:13::i;:::-;90185:27:::1;90215:18:::0;;;:13:::1;:18;::::0;;;;90292:16;;-1:-1:-1;;;;;90292:16:0::1;::::0;::::1;::::0;::::1;::::0;90262:26:::1;::::0;90281:7;;-1:-1:-1;;;90262:16:0;::::1;;:26;:::i;:::-;:46;;90254:69;;;;-1:-1:-1::0;;;90254:69:0::1;;;;;;;:::i;:::-;90336:35:::0;;90363:7;;90336:35;;:16:::1;::::0;:35:::1;::::0;90363:7;;-1:-1:-1;;;90336:35:0;::::1;-1:-1:-1::0;;;;;90336:35:0::1;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;90336:35:0::1;;;;;-1:-1:-1::0;;;;;90336:35:0::1;;;;;;90382;90388:10;90400:3;90405:7;90382:35;;;;;;;;;;;::::0;:5:::1;:35::i;:::-;90174:251;90104:321:::0;;:::o;18695:531::-;18771:7;:5;:7::i;:::-;-1:-1:-1;;;;;18757:21:0;:10;-1:-1:-1;;;;;18757:21:0;;18753:72;;18802:11;;-1:-1:-1;;;18802:11:0;;;;;;;;;;;18753:72;18910:31;;-1:-1:-1;;;18910:31:0;;;;18906:95;;;18965:24;;-1:-1:-1;;;18965:24:0;;;;;;;;;;;18906:95;19062:22;:60;;-1:-1:-1;;;;;;19133:38:0;-1:-1:-1;;;19133:38:0;;;19187:31;;;;19119:1;;19187:31;18695:531::o;89242:240::-;48866:13;:11;:13::i;:::-;89333:15:::1;::::0;;;:10:::1;:15;::::0;;;;;::::1;;89325:51;;;;-1:-1:-1::0;;;89325:51:0::1;;;;;;;:::i;:::-;89389:27;89419:18:::0;;;:13:::1;:18;::::0;;;;;89450:15:::1;;:24:::0;89242:240::o;94129:90::-;48866:13;:11;:13::i;:::-;94195:6:::1;:16:::0;;-1:-1:-1;;;;;;94195:16:0::1;-1:-1:-1::0;;;;;94195:16:0;;;::::1;::::0;;;::::1;::::0;;94129:90::o;89748:348::-;48866:13;:11;:13::i;:::-;89840:15:::1;::::0;;;:10:::1;:15;::::0;;;;;::::1;;89832:51;;;;-1:-1:-1::0;;;89832:51:0::1;;;;;;;:::i;:::-;89904:27;89934:18:::0;;;:13:::1;:18;::::0;;;;89982:16;;-1:-1:-1;;;;;89982:16:0::1;::::0;;::::1;::::0;::::1;89971:27:::0;;::::1;;;89963:86;;;::::0;-1:-1:-1;;;89963:86:0;;24363:2:1;89963:86:0::1;::::0;::::1;24345:21:1::0;24402:2;24382:18;;;24375:30;24441:34;24421:18;;;24414:62;-1:-1:-1;;;24492:18:1;;;24485:44;24546:19;;89963:86:0::1;24161:410:1::0;89963:86:0::1;90062:26:::0;;-1:-1:-1;;;;;90062:26:0;;::::1;;;-1:-1:-1::0;;90062:26:0;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;89748:348:0:o;49628:103::-;48866:13;:11;:13::i;:::-;49693:30:::1;49720:1;49693:18;:30::i;:::-;49628:103::o:0;88713:270::-;48866:13;:11;:13::i;:::-;88806:15:::1;::::0;;;:10:::1;:15;::::0;;;;;::::1;;88798:51;;;;-1:-1:-1::0;;;88798:51:0::1;;;;;;;:::i;:::-;88862:27;88892:18:::0;;;:13:::1;:18;::::0;;;;88923:13:::1;::::0;::::1;:20;88939:4:::0;88923:13;:20:::1;:::i;:::-;;88971:3;88961:14;88965:4;88961:14;;;;;;:::i;:::-;;;;;;;;88787:196;88713:270:::0;;:::o;96612:133::-;96695:7;96722:15;49053:6;;-1:-1:-1;;;;;49053:6:0;;48980:87;96722:15;96715:22;;96612:133;:::o;94345:114::-;48866:13;:11;:13::i;:::-;94423:17:::1;:28:::0;;-1:-1:-1;;;;;;94423:28:0::1;-1:-1:-1::0;;;;;94423:28:0;;;::::1;::::0;;;::::1;::::0;;94345:114::o;95407:87::-;95446:13;95479:7;95472:14;;;;;:::i;94700:310::-;94772:18;94805:28;94852:3;-1:-1:-1;;;;;94836:27:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94836:27:0;;-1:-1:-1;;94836:27:0;;;;;;;;;;;;94805:58;;94888:9;94884:89;94903:14;;;94884:89;;;94952:13;:21;94966:3;;94970:1;94966:6;;;;;;;:::i;:::-;;;;;;;;;;94952:21;;-1:-1:-1;94952:21:0;;;;;;;;;;;-1:-1:-1;94952:21:0;94937:36;;;;;;;;;;;;;;;;-1:-1:-1;;;;;94937:36:0;;;;;;;;;;;;-1:-1:-1;;;94937:36:0;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:9;94947:1;94937:12;;;;;;;;:::i;:::-;;;;;;:36;;;;94919:3;;;;;:::i;:::-;;;;94884:89;;95858:176;95962:8;14497:30;14518:8;14497:20;:30::i;:::-;95983:43:::1;96007:8;96017;95983:23;:43::i;90433:699::-:0;90541:27;90571:18;;;:13;:18;;;;;90618:22;;-1:-1:-1;;;90618:22:0;;;;90610:57;;;;-1:-1:-1;;;90610:57:0;;24778:2:1;90610:57:0;;;24760:21:1;24817:2;24797:18;;;24790:30;-1:-1:-1;;;24836:18:1;;;24829:52;24898:18;;90610:57:0;24576:346:1;90610:57:0;90716:16;;-1:-1:-1;;;;;90716:16:0;;;;;;90686:26;;90705:7;;-1:-1:-1;;;90686:16:0;;;:26;:::i;:::-;:46;;90678:69;;;;-1:-1:-1;;;90678:69:0;;;;;;;:::i;:::-;90783:10;90767:27;;;;:15;:27;;;;;;;;:32;;;;;;;;;;;90766:33;90758:60;;;;-1:-1:-1;;;90758:60:0;;25129:2:1;90758:60:0;;;25111:21:1;25168:2;25148:18;;;25141:30;-1:-1:-1;;;25187:18:1;;;25180:44;25241:18;;90758:60:0;24927:338:1;90758:60:0;90847:10;90831:27;;;;:15;:27;;;;;;;;:32;;;;;;;;:39;;-1:-1:-1;;90831:39:0;90866:4;90831:39;;;90908:42;25475:2:1;25471:15;;;;-1:-1:-1;;25467:53:1;90908:42:0;;;25455:66:1;25537:12;;;25530:28;;;25574:12;;;25567:28;;;90831:27:0;25611:12:1;;90908:42:0;;;-1:-1:-1;;90908:42:0;;;;;;;;;90898:53;;90908:42;90898:53;;;;90987:6;;90970:40;;;;;;;;;;;;;;;;;;90898:53;-1:-1:-1;90970:40:0;;-1:-1:-1;;;;;90987:6:0;;;;90898:53;;91001:8;;;;;;90970:40;;91001:8;;;;90970:40;;;;;;;;;-1:-1:-1;90970:16:0;;-1:-1:-1;;;90970:40:0:i;:::-;90962:68;;;;-1:-1:-1;;;90962:68:0;;25836:2:1;90962:68:0;;;25818:21:1;25875:2;25855:18;;;25848:30;-1:-1:-1;;;25894:18:1;;;25887:45;25949:18;;90962:68:0;25634:339:1;90962:68:0;91043:35;;91070:7;;91043:35;;:16;;:35;;91070:7;;-1:-1:-1;;;91043:35:0;;-1:-1:-1;;;;;91043:35:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;91043:35:0;;;;;-1:-1:-1;;;;;91043:35:0;;;;;;91089;91095:10;91107:3;91112:7;91089:35;;;;;;;;;;;;:5;:35::i;87125:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;89490:250::-;48866:13;:11;:13::i;:::-;89586:15:::1;::::0;;;:10:::1;:15;::::0;;;;;::::1;;89578:51;;;;-1:-1:-1::0;;;89578:51:0::1;;;;;;;:::i;:::-;89642:27;89672:18:::0;;;:13:::1;:18;::::0;;;;;89703:20:::1;;:29:::0;89490:250::o;18082:487::-;18193:7;:5;:7::i;:::-;-1:-1:-1;;;;;18179:21:0;:10;-1:-1:-1;;;;;18179:21:0;;18175:72;;18224:11;;-1:-1:-1;;;18224:11:0;;;;;;;;;;;18175:72;18332:31;;-1:-1:-1;;;18332:31:0;;;;18328:95;;;18387:24;;-1:-1:-1;;;18387:24:0;;;;;;;;;;;18328:95;18435:22;:61;;-1:-1:-1;;;;;;18435:61:0;-1:-1:-1;;;;;18435:61:0;;;;;;;;18512:49;;2298:51:1;;;18512:49:0;;2286:2:1;2271:18;18512:49:0;;;;;;;18082:487;:::o;93300:173::-;48866:13;:11;:13::i;:::-;93425:40:::1;93436:7;:5;:7::i;:::-;93445:4;93451:9;93425:40;;;;;;;;;;;::::0;:10:::1;:40::i;88991:243::-:0;48866:13;:11;:13::i;:::-;89082:15:::1;::::0;;;:10:::1;:15;::::0;;;;;::::1;;89074:51;;;;-1:-1:-1::0;;;89074:51:0::1;;;;;;;:::i;:::-;89138:27;89168:18:::0;;;:13:::1;:18;::::0;;;;;89199:27;;-1:-1:-1;;89199:27:0::1;::::0;::::1;;::::0;;;::::1;::::0;;88991:243::o;87099:19::-;;;;;;;:::i;92520:772::-;92604:27;92634:18;;;:13;:18;;;;;92673:20;;;;92665:57;;;;-1:-1:-1;;;92665:57:0;;26180:2:1;92665:57:0;;;26162:21:1;26219:2;26199:18;;;26192:30;-1:-1:-1;;;26238:18:1;;;26231:50;26298:18;;92665:57:0;25978:344:1;92665:57:0;92771:16;;-1:-1:-1;;;;;92771:16:0;;;;;;92741:26;;92760:7;;-1:-1:-1;;;92741:16:0;;;:26;:::i;:::-;:46;;92733:69;;;;-1:-1:-1;;;92733:69:0;;;;;;;:::i;:::-;92821:17;;;;92813:41;;;;-1:-1:-1;;;92813:41:0;;;;;;;:::i;:::-;92885:1;92875:7;:11;92867:35;;;;-1:-1:-1;;;92867:35:0;;;;;;;:::i;:::-;92951:7;92935:15;;:23;;;;:::i;:::-;92921:9;:38;;92913:65;;;;-1:-1:-1;;;92913:65:0;;26529:2:1;92913:65:0;;;26511:21:1;26568:2;26548:18;;;26541:30;-1:-1:-1;;;26587:18:1;;;26580:44;26641:18;;92913:65:0;26327:338:1;92913:65:0;92998:12;;93064:15;;93094:20;;;;-1:-1:-1;;;;;92998:12:0;;;;92991:33;;93039:10;;93064:15;;;93094:30;;93117:7;;93094:30;:::i;:::-;92991:144;;-1:-1:-1;;;;;;92991:144:0;;;;;;;-1:-1:-1;;;;;26928:15:1;;;92991:144:0;;;26910:34:1;26980:15;;;;26960:18;;;26953:43;27012:18;;;27005:34;26845:18;;92991:144:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;93148:35:0;;93175:7;;93148:35;;:16;;:35;;93175:7;;-1:-1:-1;;;93148:35:0;;-1:-1:-1;;;;;93148:35:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;93148:35:0;;;;;-1:-1:-1;;;;;93148:35:0;;;;;;93194;93200:10;93212:3;93217:7;93194:35;;;;;;;;;;;;:5;:35::i;:::-;93242:42;93276:7;93258:15;;:25;;;;:::i;94594:98::-;48866:13;:11;:13::i;:::-;94662:15:::1;:22:::0;94594:98::o;96042:252::-;96209:4;-1:-1:-1;;;;;14222:18:0;;14230:10;14222:18;14218:83;;14257:32;14278:10;14257:20;:32::i;:::-;96231:55:::1;96254:4;96260:2;96264:7;96273:6;96281:4;96231:22;:55::i;49886:201::-:0;48866:13;:11;:13::i;:::-;-1:-1:-1;;;;;49975:22:0;::::1;49967:73;;;::::0;-1:-1:-1;;;49967:73:0;;27502:2:1;49967:73:0::1;::::0;::::1;27484:21:1::0;27541:2;27521:18;;;27514:30;27580:34;27560:18;;;27553:62;-1:-1:-1;;;27631:18:1;;;27624:36;27677:19;;49967:73:0::1;27300:402:1::0;49967:73:0::1;50051:28;50070:8;50051:18;:28::i;91140:642::-:0;91222:27;91252:18;;;:13;:18;;;;;91291:15;;;;91283:50;;;;-1:-1:-1;;;91283:50:0;;18092:2:1;91283:50:0;;;18074:21:1;18131:2;18111:18;;;18104:30;-1:-1:-1;;;18150:18:1;;;18143:48;18208:18;;91283:50:0;17890:342:1;91283:50:0;91415:7;91397:15;;:25;;;;:::i;:::-;91385:7;91367:9;:15;;;:25;;;;:::i;:::-;91366:57;;;;:::i;:::-;91352:9;:72;;91344:99;;;;-1:-1:-1;;;91344:99:0;;18874:2:1;91344:99:0;;;18856:21:1;18913:2;18893:18;;;18886:30;-1:-1:-1;;;18932:18:1;;;18925:44;18986:18;;91344:99:0;18672:338:1;91344:99:0;91462:17;;;;91454:41;;;;-1:-1:-1;;;91454:41:0;;;;;;;:::i;:::-;91546:16;;-1:-1:-1;;;;;91546:16:0;;;;;;91516:26;;91535:7;;-1:-1:-1;;;91516:16:0;;;:26;:::i;:::-;:46;;91508:69;;;;-1:-1:-1;;;91508:69:0;;;;;;;:::i;:::-;91606:1;91596:7;:11;91588:35;;;;-1:-1:-1;;;91588:35:0;;;;;;;:::i;:::-;91636;;91663:7;;91636:35;;:16;;:35;;91663:7;;-1:-1:-1;;;91636:35:0;;-1:-1:-1;;;;;91636:35:0;;:::i;36197:716::-;36253:13;36304:14;36321:17;36332:5;36321:10;:17::i;:::-;36341:1;36321:21;36304:38;;36357:20;36391:6;-1:-1:-1;;;;;36380:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36380:18:0;-1:-1:-1;36357:41:0;-1:-1:-1;36522:28:0;;;36538:2;36522:28;36579:288;-1:-1:-1;;36611:5:0;-1:-1:-1;;;36748:2:0;36737:14;;36732:30;36611:5;36719:44;36809:2;36800:11;;;-1:-1:-1;36830:21:0;36579:288;36830:21;-1:-1:-1;36888:6:0;36197:716;-1:-1:-1;;;36197:716:0:o;49145:132::-;47611:10;49209:7;:5;:7::i;:::-;-1:-1:-1;;;;;49209:23:0;;49201:68;;;;-1:-1:-1;;;49201:68:0;;28041:2:1;49201:68:0;;;28023:21:1;;;28060:18;;;28053:30;28119:34;28099:18;;;28092:62;28171:18;;49201:68:0;27839:356:1;15348:718:0;15464:22;;-1:-1:-1;;;;;15464:22:0;15607:31;;;;;:68;;;15674:1;15650:8;-1:-1:-1;;;;;15642:29:0;;:33;15607:68;15603:456;;;15925:51;;-1:-1:-1;;;15925:51:0;;15960:4;15925:51;;;28412:34:1;-1:-1:-1;;;;;28482:15:1;;;28462:18;;;28455:43;15925:26:0;;;;;28347:18:1;;15925:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15920:128;;16004:28;;-1:-1:-1;;;16004:28:0;;-1:-1:-1;;;;;2316:32:1;;16004:28:0;;;2298:51:1;2271:18;;16004:28:0;2152:203:1;73294:438:0;-1:-1:-1;;;;;73527:20:0;;47611:10;73527:20;;:60;;-1:-1:-1;73551:36:0;73568:4;47611:10;72571:168;:::i;73551:36::-;73505:156;;;;-1:-1:-1;;;73505:156:0;;;;;;;:::i;:::-;73672:52;73695:4;73701:2;73705:3;73710:7;73719:4;73672:22;:52::i;:::-;73294:438;;;;;:::o;77992:729::-;-1:-1:-1;;;;;78145:16:0;;78137:62;;;;-1:-1:-1;;;78137:62:0;;;;;;;:::i;:::-;47611:10;78212:16;78277:21;78295:2;78277:17;:21::i;:::-;78254:44;;78309:24;78336:25;78354:6;78336:17;:25::i;:::-;78309:52;;78453:9;:13;;;;;;;;;;;-1:-1:-1;;;;;78453:17:0;;;;;;;;;:27;;78474:6;;78453:9;:27;;78474:6;;78453:27;:::i;:::-;;;;-1:-1:-1;;78496:52:0;;;29500:25:1;;;29556:2;29541:18;;29534:34;;;-1:-1:-1;;;;;78496:52:0;;;;78529:1;;78496:52;;;;;;29473:18:1;78496:52:0;;;;;;;78639:74;78670:8;78688:1;78692:2;78696;78700:6;78708:4;78639:30;:74::i;:::-;78126:595;;;77992:729;;;;:::o;95502:166::-;95590:17;;95582:51;;95564:12;;-1:-1:-1;;;;;95590:17:0;;95622:6;;95564:12;95582:51;95564:12;95582:51;95622:6;95590:17;95582:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95563:70;;;95652:7;95644:16;;;;;80235:808;-1:-1:-1;;;;;80362:18:0;;80354:66;;;;-1:-1:-1;;;80354:66:0;;29781:2:1;80354:66:0;;;29763:21:1;29820:2;29800:18;;;29793:30;29859:34;29839:18;;;29832:62;-1:-1:-1;;;29910:18:1;;;29903:33;29953:19;;80354:66:0;29579:399:1;80354:66:0;47611:10;80433:16;80498:21;80516:2;80498:17;:21::i;:::-;80475:44;;80530:24;80557:25;80575:6;80557:17;:25::i;:::-;80595:66;;;;;;;;;-1:-1:-1;80595:66:0;;;;80696:13;;;;;;;;;-1:-1:-1;;;;;80696:19:0;;;;;;;;80530:52;;-1:-1:-1;80734:21:0;;;;80726:70;;;;-1:-1:-1;;;80726:70:0;;30185:2:1;80726:70:0;;;30167:21:1;30224:2;30204:18;;;30197:30;30263:34;30243:18;;;30236:62;-1:-1:-1;;;30314:18:1;;;30307:34;30358:19;;80726:70:0;29983:400:1;80726:70:0;80832:9;:13;;;;;;;;;;;-1:-1:-1;;;;;80832:19:0;;;;;;;;;;;;80854:20;;;80832:42;;80903:54;;29500:25:1;;;29541:18;;;29534:34;;;80832:19:0;;80903:54;;;;;;29473:18:1;80903:54:0;;;;;;;80970:65;;;;;;;;;81014:1;80970:65;;;96302:302;50247:191;50340:6;;;-1:-1:-1;;;;;50357:17:0;;;-1:-1:-1;;;;;;50357:17:0;;;;;;;50390:40;;50340:6;;;50357:17;50340:6;;50390:40;;50321:16;;50390:40;50310:128;50247:191;:::o;72344:155::-;72439:52;47611:10;72472:8;72482;72439:18;:52::i;93911:210::-;94016:4;94051:62;94065:35;94094:5;45739:58;;35246:66:1;45739:58:0;;;35234:79:1;35329:12;;;35322:28;;;45606:7:0;;35366:12:1;;45739:58:0;;;;;;;;;;;;45729:69;;;;;;45722:76;;45537:269;;;;94065:35;94102:10;94051:13;:62::i;:::-;-1:-1:-1;;;;;94040:73:0;:7;-1:-1:-1;;;;;94040:73:0;;94033:80;;93911:210;;;;;:::o;79124:813::-;-1:-1:-1;;;;;79302:16:0;;79294:62;;;;-1:-1:-1;;;79294:62:0;;;;;;;:::i;:::-;79389:7;:14;79375:3;:10;:28;79367:81;;;;-1:-1:-1;;;79367:81:0;;;;;;;:::i;:::-;47611:10;79461:16;79584:103;79608:3;:10;79604:1;:14;79584:103;;;79665:7;79673:1;79665:10;;;;;;;;:::i;:::-;;;;;;;79640:9;:17;79650:3;79654:1;79650:6;;;;;;;;:::i;:::-;;;;;;;79640:17;;;;;;;;;;;:21;79658:2;-1:-1:-1;;;;;79640:21:0;-1:-1:-1;;;;;79640:21:0;;;;;;;;;;;;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;79620:3:0;;-1:-1:-1;79620:3:0;;;:::i;:::-;;;;79584:103;;;;79740:2;-1:-1:-1;;;;;79704:53:0;79736:1;-1:-1:-1;;;;;79704:53:0;79718:8;-1:-1:-1;;;;;79704:53:0;;79744:3;79749:7;79704:53;;;;;;;:::i;:::-;;;;;;;;79848:81;79884:8;79902:1;79906:2;79910:3;79915:7;79924:4;79848:35;:81::i;72811:406::-;-1:-1:-1;;;;;73019:20:0;;47611:10;73019:20;;:60;;-1:-1:-1;73043:36:0;73060:4;47611:10;72571:168;:::i;73043:36::-;72997:156;;;;-1:-1:-1;;;72997:156:0;;;;;;;:::i;:::-;73164:45;73182:4;73188:2;73192;73196:6;73204:4;73164:17;:45::i;33063:922::-;33116:7;;-1:-1:-1;;;33194:15:0;;33190:102;;-1:-1:-1;;;33230:15:0;;;-1:-1:-1;33274:2:0;33264:12;33190:102;33319:6;33310:5;:15;33306:102;;33355:6;33346:15;;;-1:-1:-1;33390:2:0;33380:12;33306:102;33435:6;33426:5;:15;33422:102;;33471:6;33462:15;;;-1:-1:-1;33506:2:0;33496:12;33422:102;33551:5;33542;:14;33538:99;;33586:5;33577:14;;;-1:-1:-1;33620:1:0;33610:11;33538:99;33664:5;33655;:14;33651:99;;33699:5;33690:14;;;-1:-1:-1;33733:1:0;33723:11;33651:99;33777:5;33768;:14;33764:99;;33812:5;33803:14;;;-1:-1:-1;33846:1:0;33836:11;33764:99;33890:5;33881;:14;33877:66;;33926:1;33916:11;33971:6;33063:922;-1:-1:-1;;33063:922:0:o;75528:1146::-;75755:7;:14;75741:3;:10;:28;75733:81;;;;-1:-1:-1;;;75733:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;75833:16:0;;75825:66;;;;-1:-1:-1;;;75825:66:0;;;;;;;:::i;:::-;47611:10;75904:16;76021:421;76045:3;:10;76041:1;:14;76021:421;;;76077:10;76090:3;76094:1;76090:6;;;;;;;;:::i;:::-;;;;;;;76077:19;;76111:14;76128:7;76136:1;76128:10;;;;;;;;:::i;:::-;;;;;;;;;;;;76155:19;76177:13;;;;;;;;;;-1:-1:-1;;;;;76177:19:0;;;;;;;;;;;;76128:10;;-1:-1:-1;76219:21:0;;;;76211:76;;;;-1:-1:-1;;;76211:76:0;;;;;;;:::i;:::-;76331:9;:13;;;;;;;;;;;-1:-1:-1;;;;;76331:19:0;;;;;;;;;;76353:20;;;76331:42;;76403:17;;;;;;;:27;;76353:20;;76331:9;76403:27;;76353:20;;76403:27;:::i;:::-;;;;;;;;76062:380;;;76057:3;;;;:::i;:::-;;;76021:421;;;;76489:2;-1:-1:-1;;;;;76459:47:0;76483:4;-1:-1:-1;;;;;76459:47:0;76473:8;-1:-1:-1;;;;;76459:47:0;;76493:3;76498:7;76459:47;;;;;;;:::i;:::-;;;;;;;;76591:75;76627:8;76637:4;76643:2;76647:3;76652:7;76661:4;76591:35;:75::i;86671:198::-;86791:16;;;86805:1;86791:16;;;;;;;;;86737;;86766:22;;86791:16;;;;;;;;;;;;-1:-1:-1;86791:16:0;86766:41;;86829:7;86818:5;86824:1;86818:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;86856:5;86671:198;-1:-1:-1;;86671:198:0:o;85098:744::-;-1:-1:-1;;;;;85313:13:0;;51973:19;:23;85309:526;;85349:72;;-1:-1:-1;;;85349:72:0;;-1:-1:-1;;;;;85349:38:0;;;;;:72;;85388:8;;85398:4;;85404:2;;85408:6;;85416:4;;85349:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;85349:72:0;;;;;;;;-1:-1:-1;;85349:72:0;;;;;;;;;;;;:::i;:::-;;;85345:479;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;85697:6;85690:14;;-1:-1:-1;;;85690:14:0;;;;;;;;:::i;85345:479::-;;;85746:62;;-1:-1:-1;;;85746:62:0;;33966:2:1;85746:62:0;;;33948:21:1;34005:2;33985:18;;;33978:30;34044:34;34024:18;;;34017:62;-1:-1:-1;;;34095:18:1;;;34088:50;34155:19;;85746:62:0;33764:416:1;85345:479:0;-1:-1:-1;;;;;;85471:55:0;;-1:-1:-1;;;85471:55:0;85467:154;;85551:50;;-1:-1:-1;;;85551:50:0;;;;;;;:::i;82405:331::-;82560:8;-1:-1:-1;;;;;82551:17:0;:5;-1:-1:-1;;;;;82551:17:0;;82543:71;;;;-1:-1:-1;;;82543:71:0;;34796:2:1;82543:71:0;;;34778:21:1;34835:2;34815:18;;;34808:30;34874:34;34854:18;;;34847:62;-1:-1:-1;;;34925:18:1;;;34918:39;34974:19;;82543:71:0;34594:405:1;82543:71:0;-1:-1:-1;;;;;82625:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;82625:46:0;;;;;;;;;;82687:41;;1159::1;;;82687::0;;1132:18:1;82687:41:0;;;;;;;82405:331;;;:::o;41847:231::-;41925:7;41946:17;41965:18;41987:27;41998:4;42004:9;41987:10;:27::i;:::-;41945:69;;;;42025:18;42037:5;42025:11;:18::i;85850:813::-;-1:-1:-1;;;;;86090:13:0;;51973:19;:23;86086:570;;86126:79;;-1:-1:-1;;;86126:79:0;;-1:-1:-1;;;;;86126:43:0;;;;;:79;;86170:8;;86180:4;;86186:3;;86191:7;;86200:4;;86126:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;86126:79:0;;;;;;;;-1:-1:-1;;86126:79:0;;;;;;;;;;;;:::i;:::-;;;86122:523;;;;:::i;:::-;-1:-1:-1;;;;;;86287:60:0;;-1:-1:-1;;;86287:60:0;86283:159;;86372:50;;-1:-1:-1;;;86372:50:0;;;;;;;:::i;74196:974::-;-1:-1:-1;;;;;74384:16:0;;74376:66;;;;-1:-1:-1;;;74376:66:0;;;;;;;:::i;:::-;47611:10;74455:16;74520:21;74538:2;74520:17;:21::i;:::-;74497:44;;74552:24;74579:25;74597:6;74579:17;:25::i;:::-;74552:52;;74690:19;74712:13;;;;;;;;;;;-1:-1:-1;;;;;74712:19:0;;;;;;;;;;74750:21;;;;74742:76;;;;-1:-1:-1;;;74742:76:0;;;;;;;:::i;:::-;74854:9;:13;;;;;;;;;;;-1:-1:-1;;;;;74854:19:0;;;;;;;;;;74876:20;;;74854:42;;74918:17;;;;;;;:27;;74876:20;;74854:9;74918:27;;74876:20;;74918:27;:::i;:::-;;;;-1:-1:-1;;74963:46:0;;;29500:25:1;;;29556:2;29541:18;;29534:34;;;-1:-1:-1;;;;;74963:46:0;;;;;;;;;;;;;;29473:18:1;74963:46:0;;;;;;;75094:68;75125:8;75135:4;75141:2;75145;75149:6;75157:4;75094:30;:68::i;:::-;74365:805;;;;74196:974;;;;;:::o;40298:747::-;40379:7;40388:12;40417:9;:16;40437:2;40417:22;40413:625;;40761:4;40746:20;;40740:27;40811:4;40796:20;;40790:27;40869:4;40854:20;;40848:27;40456:9;40840:36;40912:25;40923:4;40840:36;40740:27;40790;40912:10;:25::i;:::-;40905:32;;;;;;;;;40413:625;-1:-1:-1;40986:1:0;;-1:-1:-1;40990:35:0;40413:625;40298:747;;;;;:::o;38691:521::-;38769:20;38760:5;:29;;;;;;;;:::i;:::-;;38756:449;;38691:521;:::o;38756:449::-;38867:29;38858:5;:38;;;;;;;;:::i;:::-;;38854:351;;38913:34;;-1:-1:-1;;;38913:34:0;;36555:2:1;38913:34:0;;;36537:21:1;36594:2;36574:18;;;36567:30;36633:26;36613:18;;;36606:54;36677:18;;38913:34:0;36353:348:1;38854:351:0;38978:35;38969:5;:44;;;;;;;;:::i;:::-;;38965:240;;39030:41;;-1:-1:-1;;;39030:41:0;;36908:2:1;39030:41:0;;;36890:21:1;36947:2;36927:18;;;36920:30;36986:33;36966:18;;;36959:61;37037:18;;39030:41:0;36706:355:1;38965:240:0;39102:30;39093:5;:39;;;;;;;;:::i;:::-;;39089:116;;39149:44;;-1:-1:-1;;;39149:44:0;;37268:2:1;39149:44:0;;;37250:21:1;37307:2;37287:18;;;37280:30;37346:34;37326:18;;;37319:62;-1:-1:-1;;;37397:18:1;;;37390:32;37439:19;;39149:44:0;37066:398:1;43299:1520:0;43430:7;;44364:66;44351:79;;44347:163;;;-1:-1:-1;44463:1:0;;-1:-1:-1;44467:30:0;44447:51;;44347:163;44624:24;;;44607:14;44624:24;;;;;;;;;37696:25:1;;;37769:4;37757:17;;37737:18;;;37730:45;;;;37791:18;;;37784:34;;;37834:18;;;37827:34;;;44624:24:0;;37668:19:1;;44624:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44624:24:0;;-1:-1:-1;;44624:24:0;;;-1:-1:-1;;;;;;;44663:20:0;;44659:103;;44716:1;44720:29;44700:50;;;;;;;44659:103;44782:6;-1:-1:-1;44790:20:0;;-1:-1:-1;43299:1520:0;;;;;;;;:::o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:254::-;260:6;268;321:2;309:9;300:7;296:23;292:32;289:52;;;337:1;334;327:12;289:52;360:29;379:9;360:29;:::i;:::-;350:39;436:2;421:18;;;;408:32;;-1:-1:-1;;;192:254:1:o;633:131::-;-1:-1:-1;;;;;;707:32:1;;697:43;;687:71;;754:1;751;744:12;769:245;827:6;880:2;868:9;859:7;855:23;851:32;848:52;;;896:1;893;886:12;848:52;935:9;922:23;954:30;978:5;954:30;:::i;:::-;1003:5;769:245;-1:-1:-1;;;769:245:1:o;1211:250::-;1296:1;1306:113;1320:6;1317:1;1314:13;1306:113;;;1396:11;;;1390:18;1377:11;;;1370:39;1342:2;1335:10;1306:113;;;-1:-1:-1;;1453:1:1;1435:16;;1428:27;1211:250::o;1466:271::-;1508:3;1546:5;1540:12;1573:6;1568:3;1561:19;1589:76;1658:6;1651:4;1646:3;1642:14;1635:4;1628:5;1624:16;1589:76;:::i;:::-;1719:2;1698:15;-1:-1:-1;;1694:29:1;1685:39;;;;1726:4;1681:50;;1466:271;-1:-1:-1;;1466:271:1:o;1742:220::-;1891:2;1880:9;1873:21;1854:4;1911:45;1952:2;1941:9;1937:18;1929:6;1911:45;:::i;1967:180::-;2026:6;2079:2;2067:9;2058:7;2054:23;2050:32;2047:52;;;2095:1;2092;2085:12;2047:52;-1:-1:-1;2118:23:1;;1967:180;-1:-1:-1;1967:180:1:o;2360:186::-;2419:6;2472:2;2460:9;2451:7;2447:23;2443:32;2440:52;;;2488:1;2485;2478:12;2440:52;2511:29;2530:9;2511:29;:::i;2551:127::-;2612:10;2607:3;2603:20;2600:1;2593:31;2643:4;2640:1;2633:15;2667:4;2664:1;2657:15;2683:249;2793:2;2774:13;;-1:-1:-1;;2770:27:1;2758:40;;-1:-1:-1;;;;;2813:34:1;;2849:22;;;2810:62;2807:88;;;2875:18;;:::i;:::-;2911:2;2904:22;-1:-1:-1;;2683:249:1:o;2937:183::-;2997:4;-1:-1:-1;;;;;3022:6:1;3019:30;3016:56;;;3052:18;;:::i;:::-;-1:-1:-1;3097:1:1;3093:14;3109:4;3089:25;;2937:183::o;3125:724::-;3179:5;3232:3;3225:4;3217:6;3213:17;3209:27;3199:55;;3250:1;3247;3240:12;3199:55;3286:6;3273:20;3312:4;3335:43;3375:2;3335:43;:::i;:::-;3407:2;3401:9;3419:31;3447:2;3439:6;3419:31;:::i;:::-;3485:18;;;3577:1;3573:10;;;;3561:23;;3557:32;;;3519:15;;;;-1:-1:-1;3601:15:1;;;3598:35;;;3629:1;3626;3619:12;3598:35;3665:2;3657:6;3653:15;3677:142;3693:6;3688:3;3685:15;3677:142;;;3759:17;;3747:30;;3797:12;;;;3710;;3677:142;;;-1:-1:-1;3837:6:1;3125:724;-1:-1:-1;;;;;;3125:724:1:o;3854:555::-;3896:5;3949:3;3942:4;3934:6;3930:17;3926:27;3916:55;;3967:1;3964;3957:12;3916:55;4003:6;3990:20;-1:-1:-1;;;;;4025:2:1;4022:26;4019:52;;;4051:18;;:::i;:::-;4100:2;4094:9;4112:67;4167:2;4148:13;;-1:-1:-1;;4144:27:1;4173:4;4140:38;4094:9;4112:67;:::i;:::-;4203:2;4195:6;4188:18;4249:3;4242:4;4237:2;4229:6;4225:15;4221:26;4218:35;4215:55;;;4266:1;4263;4256:12;4215:55;4330:2;4323:4;4315:6;4311:17;4304:4;4296:6;4292:17;4279:54;4377:1;4353:15;;;4370:4;4349:26;4342:37;;;;4357:6;3854:555;-1:-1:-1;;;3854:555:1:o;4414:943::-;4568:6;4576;4584;4592;4600;4653:3;4641:9;4632:7;4628:23;4624:33;4621:53;;;4670:1;4667;4660:12;4621:53;4693:29;4712:9;4693:29;:::i;:::-;4683:39;;4741:38;4775:2;4764:9;4760:18;4741:38;:::i;:::-;4731:48;;4830:2;4819:9;4815:18;4802:32;-1:-1:-1;;;;;4894:2:1;4886:6;4883:14;4880:34;;;4910:1;4907;4900:12;4880:34;4933:61;4986:7;4977:6;4966:9;4962:22;4933:61;:::i;:::-;4923:71;;5047:2;5036:9;5032:18;5019:32;5003:48;;5076:2;5066:8;5063:16;5060:36;;;5092:1;5089;5082:12;5060:36;5115:63;5170:7;5159:8;5148:9;5144:24;5115:63;:::i;:::-;5105:73;;5231:3;5220:9;5216:19;5203:33;5187:49;;5261:2;5251:8;5248:16;5245:36;;;5277:1;5274;5267:12;5245:36;;5300:51;5343:7;5332:8;5321:9;5317:24;5300:51;:::i;:::-;5290:61;;;4414:943;;;;;;;;:::o;5362:322::-;5439:6;5447;5455;5508:2;5496:9;5487:7;5483:23;5479:32;5476:52;;;5524:1;5521;5514:12;5476:52;5547:29;5566:9;5547:29;:::i;:::-;5537:39;5623:2;5608:18;;5595:32;;-1:-1:-1;5674:2:1;5659:18;;;5646:32;;5362:322;-1:-1:-1;;;5362:322:1:o;5689:118::-;5775:5;5768:13;5761:21;5754:5;5751:32;5741:60;;5797:1;5794;5787:12;5812:171;5879:20;;-1:-1:-1;;;;;5928:30:1;;5918:41;;5908:69;;5973:1;5970;5963:12;5988:729;6098:6;6106;6114;6122;6130;6138;6191:3;6179:9;6170:7;6166:23;6162:33;6159:53;;;6208:1;6205;6198:12;6159:53;6244:9;6231:23;6221:33;;6304:2;6293:9;6289:18;6276:32;6317:28;6339:5;6317:28;:::i;:::-;6364:5;-1:-1:-1;6388:37:1;6421:2;6406:18;;6388:37;:::i;:::-;6378:47;;6476:2;6465:9;6461:18;6448:32;-1:-1:-1;;;;;6495:6:1;6492:30;6489:50;;;6535:1;6532;6525:12;6489:50;6558:49;6599:7;6590:6;6579:9;6575:22;6558:49;:::i;:::-;6548:59;;;6654:3;6643:9;6639:19;6626:33;6616:43;;6706:3;6695:9;6691:19;6678:33;6668:43;;5988:729;;;;;;;;:::o;6722:1208::-;6840:6;6848;6901:2;6889:9;6880:7;6876:23;6872:32;6869:52;;;6917:1;6914;6907:12;6869:52;6957:9;6944:23;-1:-1:-1;;;;;7027:2:1;7019:6;7016:14;7013:34;;;7043:1;7040;7033:12;7013:34;7081:6;7070:9;7066:22;7056:32;;7126:7;7119:4;7115:2;7111:13;7107:27;7097:55;;7148:1;7145;7138:12;7097:55;7184:2;7171:16;7206:4;7229:43;7269:2;7229:43;:::i;:::-;7301:2;7295:9;7313:31;7341:2;7333:6;7313:31;:::i;:::-;7379:18;;;7467:1;7463:10;;;;7455:19;;7451:28;;;7413:15;;;;-1:-1:-1;7491:19:1;;;7488:39;;;7523:1;7520;7513:12;7488:39;7547:11;;;;7567:148;7583:6;7578:3;7575:15;7567:148;;;7649:23;7668:3;7649:23;:::i;:::-;7637:36;;7600:12;;;;7693;;;;7567:148;;;7734:6;-1:-1:-1;;7778:18:1;;7765:32;;-1:-1:-1;;7809:16:1;;;7806:36;;;7838:1;7835;7828:12;7806:36;;7861:63;7916:7;7905:8;7894:9;7890:24;7861:63;:::i;:::-;7851:73;;;6722:1208;;;;;:::o;7935:435::-;7988:3;8026:5;8020:12;8053:6;8048:3;8041:19;8079:4;8108:2;8103:3;8099:12;8092:19;;8145:2;8138:5;8134:14;8166:1;8176:169;8190:6;8187:1;8184:13;8176:169;;;8251:13;;8239:26;;8285:12;;;;8320:15;;;;8212:1;8205:9;8176:169;;;-1:-1:-1;8361:3:1;;7935:435;-1:-1:-1;;;;;7935:435:1:o;8375:261::-;8554:2;8543:9;8536:21;8517:4;8574:56;8626:2;8615:9;8611:18;8603:6;8574:56;:::i;8641:254::-;8709:6;8717;8770:2;8758:9;8749:7;8745:23;8741:32;8738:52;;;8786:1;8783;8776:12;8738:52;8822:9;8809:23;8799:33;;8851:38;8885:2;8874:9;8870:18;8851:38;:::i;:::-;8841:48;;8641:254;;;;;:::o;8900:640::-;9193:6;9186:14;9179:22;9168:9;9161:41;9142:4;-1:-1:-1;;;;;9287:2:1;9279:6;9275:15;9270:2;9259:9;9255:18;9248:43;9339:2;9331:6;9327:15;9322:2;9311:9;9307:18;9300:43;;9379:3;9374:2;9363:9;9359:18;9352:31;9400:46;9441:3;9430:9;9426:19;9418:6;9400:46;:::i;:::-;9477:3;9462:19;;9455:35;;;;-1:-1:-1;9521:3:1;9506:19;9499:35;9392:54;8900:640;-1:-1:-1;;;;8900:640:1:o;9545:248::-;9613:6;9621;9674:2;9662:9;9653:7;9649:23;9645:32;9642:52;;;9690:1;9687;9680:12;9642:52;-1:-1:-1;;9713:23:1;;;9783:2;9768:18;;;9755:32;;-1:-1:-1;9545:248:1:o;9798:252::-;9865:6;9873;9926:2;9914:9;9905:7;9901:23;9897:32;9894:52;;;9942:1;9939;9932:12;9894:52;9978:9;9965:23;9955:33;;10007:37;10040:2;10029:9;10025:18;10007:37;:::i;10055:389::-;10133:6;10141;10194:2;10182:9;10173:7;10169:23;10165:32;10162:52;;;10210:1;10207;10200:12;10162:52;10246:9;10233:23;10223:33;;10307:2;10296:9;10292:18;10279:32;-1:-1:-1;;;;;10326:6:1;10323:30;10320:50;;;10366:1;10363;10356:12;10320:50;10389:49;10430:7;10421:6;10410:9;10406:22;10389:49;:::i;10449:615::-;10535:6;10543;10596:2;10584:9;10575:7;10571:23;10567:32;10564:52;;;10612:1;10609;10602:12;10564:52;10652:9;10639:23;-1:-1:-1;;;;;10722:2:1;10714:6;10711:14;10708:34;;;10738:1;10735;10728:12;10708:34;10776:6;10765:9;10761:22;10751:32;;10821:7;10814:4;10810:2;10806:13;10802:27;10792:55;;10843:1;10840;10833:12;10792:55;10883:2;10870:16;10909:2;10901:6;10898:14;10895:34;;;10925:1;10922;10915:12;10895:34;10978:7;10973:2;10963:6;10960:1;10956:14;10952:2;10948:23;10944:32;10941:45;10938:65;;;10999:1;10996;10989:12;10938:65;11030:2;11022:11;;;;;11052:6;;-1:-1:-1;10449:615:1;;-1:-1:-1;;;;10449:615:1:o;11069:1520::-;11265:4;11294:2;11334;11323:9;11319:18;11364:2;11353:9;11346:21;11387:6;11422;11416:13;11453:6;11445;11438:22;11479:2;11469:12;;11512:2;11501:9;11497:18;11490:25;;11574:2;11564:6;11561:1;11557:14;11546:9;11542:30;11538:39;11612:2;11604:6;11600:15;11633:1;11643:917;11657:6;11654:1;11651:13;11643:917;;;11722:22;;;-1:-1:-1;;11718:36:1;11706:49;;11778:13;;11860:9;;11853:17;11846:25;11831:41;;11911:11;;;11905:18;-1:-1:-1;;;;;12001:21:1;;;11984:15;;;11977:46;12070:11;;;12064:18;12060:27;12043:15;;;12036:52;12111:4;12156:11;;;12150:18;11814:4;12188:15;;;12181:27;;;11814:4;12111;12235:50;12269:15;;;12150:18;12235:50;:::i;:::-;12308:4;12355:11;;;12349:18;12332:15;;;12325:43;12391:4;12438:11;;;12432:18;12415:15;;;;12408:43;;;;-1:-1:-1;;;12538:12:1;;;;12503:15;;;;11679:1;11672:9;11643:917;;;-1:-1:-1;12577:6:1;;11069:1520;-1:-1:-1;;;;;;;;11069:1520:1:o;12594:315::-;12659:6;12667;12720:2;12708:9;12699:7;12695:23;12691:32;12688:52;;;12736:1;12733;12726:12;12688:52;12759:29;12778:9;12759:29;:::i;:::-;12749:39;;12838:2;12827:9;12823:18;12810:32;12851:28;12873:5;12851:28;:::i;:::-;12898:5;12888:15;;;12594:315;;;;;:::o;12914:733::-;13002:6;13010;13018;13026;13079:2;13067:9;13058:7;13054:23;13050:32;13047:52;;;13095:1;13092;13085:12;13047:52;13135:9;13122:23;-1:-1:-1;;;;;13205:2:1;13197:6;13194:14;13191:34;;;13221:1;13218;13211:12;13191:34;13259:6;13248:9;13244:22;13234:32;;13304:7;13297:4;13293:2;13289:13;13285:27;13275:55;;13326:1;13323;13316:12;13275:55;13366:2;13353:16;13392:2;13384:6;13381:14;13378:34;;;13408:1;13405;13398:12;13378:34;13455:7;13448:4;13439:6;13435:2;13431:15;13427:26;13424:39;13421:59;;;13476:1;13473;13466:12;13421:59;13507:4;13499:13;;;;13531:6;;-1:-1:-1;13569:20:1;;;13556:34;;13637:2;13622:18;13609:32;;-1:-1:-1;12914:733:1;;-1:-1:-1;;;;12914:733:1:o;13891:595::-;14009:6;14017;14070:2;14058:9;14049:7;14045:23;14041:32;14038:52;;;14086:1;14083;14076:12;14038:52;14126:9;14113:23;-1:-1:-1;;;;;14196:2:1;14188:6;14185:14;14182:34;;;14212:1;14209;14202:12;14182:34;14235:61;14288:7;14279:6;14268:9;14264:22;14235:61;:::i;:::-;14225:71;;14349:2;14338:9;14334:18;14321:32;14305:48;;14378:2;14368:8;14365:16;14362:36;;;14394:1;14391;14384:12;14491:309;14556:6;14564;14617:2;14605:9;14596:7;14592:23;14588:32;14585:52;;;14633:1;14630;14623:12;14585:52;14669:9;14656:23;14646:33;;14729:2;14718:9;14714:18;14701:32;14742:28;14764:5;14742:28;:::i;14805:260::-;14873:6;14881;14934:2;14922:9;14913:7;14909:23;14905:32;14902:52;;;14950:1;14947;14940:12;14902:52;14973:29;14992:9;14973:29;:::i;:::-;14963:39;;15021:38;15055:2;15044:9;15040:18;15021:38;:::i;15070:606::-;15174:6;15182;15190;15198;15206;15259:3;15247:9;15238:7;15234:23;15230:33;15227:53;;;15276:1;15273;15266:12;15227:53;15299:29;15318:9;15299:29;:::i;:::-;15289:39;;15347:38;15381:2;15370:9;15366:18;15347:38;:::i;:::-;15337:48;;15432:2;15421:9;15417:18;15404:32;15394:42;;15483:2;15472:9;15468:18;15455:32;15445:42;;15538:3;15527:9;15523:19;15510:33;-1:-1:-1;;;;;15558:6:1;15555:30;15552:50;;;15598:1;15595;15588:12;15552:50;15621:49;15662:7;15653:6;15642:9;15638:22;15621:49;:::i;16092:380::-;16171:1;16167:12;;;;16214;;;16235:61;;16289:4;16281:6;16277:17;16267:27;;16235:61;16342:2;16334:6;16331:14;16311:18;16308:38;16305:161;;16388:10;16383:3;16379:20;16376:1;16369:31;16423:4;16420:1;16413:15;16451:4;16448:1;16441:15;16305:161;;16092:380;;;:::o;16836:496::-;17015:3;17053:6;17047:13;17069:66;17128:6;17123:3;17116:4;17108:6;17104:17;17069:66;:::i;:::-;17198:13;;17157:16;;;;17220:70;17198:13;17157:16;17267:4;17255:17;;17220:70;:::i;:::-;17306:20;;16836:496;-1:-1:-1;;;;16836:496:1:o;18237:127::-;18298:10;18293:3;18289:20;18286:1;18279:31;18329:4;18326:1;18319:15;18353:4;18350:1;18343:15;18369:168;18442:9;;;18473;;18490:15;;;18484:22;;18470:37;18460:71;;18511:18;;:::i;18542:125::-;18607:9;;;18628:10;;;18625:36;;;18641:18;;:::i;19015:335::-;19217:2;19199:21;;;19256:2;19236:18;;;19229:30;-1:-1:-1;;;19290:2:1;19275:18;;19268:41;19341:2;19326:18;;19015:335::o;19355:334::-;19557:2;19539:21;;;19596:2;19576:18;;;19569:30;-1:-1:-1;;;19630:2:1;19615:18;;19608:40;19680:2;19665:18;;19355:334::o;19694:335::-;19896:2;19878:21;;;19935:2;19915:18;;;19908:30;-1:-1:-1;;;19969:2:1;19954:18;;19947:41;20020:2;20005:18;;19694:335::o;20034:180::-;-1:-1:-1;;;;;20139:10:1;;;20151;;;20135:27;;20174:11;;;20171:37;;;20188:18;;:::i;:::-;20171:37;20034:180;;;;:::o;20698:545::-;20800:2;20795:3;20792:11;20789:448;;;20836:1;20861:5;20857:2;20850:17;20906:4;20902:2;20892:19;20976:2;20964:10;20960:19;20957:1;20953:27;20947:4;20943:38;21012:4;21000:10;20997:20;20994:47;;;-1:-1:-1;21035:4:1;20994:47;21090:2;21085:3;21081:12;21078:1;21074:20;21068:4;21064:31;21054:41;;21145:82;21163:2;21156:5;21153:13;21145:82;;;21208:17;;;21189:1;21178:13;21145:82;;21419:1352;21545:3;21539:10;-1:-1:-1;;;;;21564:6:1;21561:30;21558:56;;;21594:18;;:::i;:::-;21623:97;21713:6;21673:38;21705:4;21699:11;21673:38;:::i;:::-;21667:4;21623:97;:::i;:::-;21775:4;;21839:2;21828:14;;21856:1;21851:663;;;;22558:1;22575:6;22572:89;;;-1:-1:-1;22627:19:1;;;22621:26;22572:89;-1:-1:-1;;21376:1:1;21372:11;;;21368:24;21364:29;21354:40;21400:1;21396:11;;;21351:57;22674:81;;21821:944;;21851:663;20645:1;20638:14;;;20682:4;20669:18;;-1:-1:-1;;21887:20:1;;;22005:236;22019:7;22016:1;22013:14;22005:236;;;22108:19;;;22102:26;22087:42;;22200:27;;;;22168:1;22156:14;;;;22035:19;;22005:236;;;22009:3;22269:6;22260:7;22257:19;22254:201;;;22330:19;;;22324:26;-1:-1:-1;;22413:1:1;22409:14;;;22425:3;22405:24;22401:37;22397:42;22382:58;22367:74;;22254:201;-1:-1:-1;;;;;22501:1:1;22485:14;;;22481:22;22468:36;;-1:-1:-1;21419:1352:1:o;23186:127::-;23247:10;23242:3;23238:20;23235:1;23228:31;23278:4;23275:1;23268:15;23302:4;23299:1;23292:15;23318:135;23357:3;23378:17;;;23375:43;;23398:18;;:::i;:::-;-1:-1:-1;23445:1:1;23434:13;;23318:135::o;23809:347::-;24011:2;23993:21;;;24050:2;24030:18;;;24023:30;24089:25;24084:2;24069:18;;24062:53;24147:2;24132:18;;23809:347::o;27050:245::-;27117:6;27170:2;27158:9;27149:7;27145:23;27141:32;27138:52;;;27186:1;27183;27176:12;27138:52;27218:9;27212:16;27237:28;27259:5;27237:28;:::i;28509:410::-;28711:2;28693:21;;;28750:2;28730:18;;;28723:30;28789:34;28784:2;28769:18;;28762:62;-1:-1:-1;;;28855:2:1;28840:18;;28833:44;28909:3;28894:19;;28509:410::o;28924:397::-;29126:2;29108:21;;;29165:2;29145:18;;;29138:30;29204:34;29199:2;29184:18;;29177:62;-1:-1:-1;;;29270:2:1;29255:18;;29248:31;29311:3;29296:19;;28924:397::o;30388:404::-;30590:2;30572:21;;;30629:2;30609:18;;;30602:30;30668:34;30663:2;30648:18;;30641:62;-1:-1:-1;;;30734:2:1;30719:18;;30712:38;30782:3;30767:19;;30388:404::o;30797:465::-;31054:2;31043:9;31036:21;31017:4;31080:56;31132:2;31121:9;31117:18;31109:6;31080:56;:::i;:::-;31184:9;31176:6;31172:22;31167:2;31156:9;31152:18;31145:50;31212:44;31249:6;31241;31212:44;:::i;:::-;31204:52;30797:465;-1:-1:-1;;;;;30797:465:1:o;31267:401::-;31469:2;31451:21;;;31508:2;31488:18;;;31481:30;31547:34;31542:2;31527:18;;31520:62;-1:-1:-1;;;31613:2:1;31598:18;;31591:35;31658:3;31643:19;;31267:401::o;31673:406::-;31875:2;31857:21;;;31914:2;31894:18;;;31887:30;31953:34;31948:2;31933:18;;31926:62;-1:-1:-1;;;32019:2:1;32004:18;;31997:40;32069:3;32054:19;;31673:406::o;32084:561::-;-1:-1:-1;;;;;32381:15:1;;;32363:34;;32433:15;;32428:2;32413:18;;32406:43;32480:2;32465:18;;32458:34;;;32523:2;32508:18;;32501:34;;;32343:3;32566;32551:19;;32544:32;;;32306:4;;32593:46;;32619:19;;32611:6;32593:46;:::i;:::-;32585:54;32084:561;-1:-1:-1;;;;;;;32084:561:1:o;32650:249::-;32719:6;32772:2;32760:9;32751:7;32747:23;32743:32;32740:52;;;32788:1;32785;32778:12;32740:52;32820:9;32814:16;32839:30;32863:5;32839:30;:::i;32904:179::-;32939:3;32981:1;32963:16;32960:23;32957:120;;;33027:1;33024;33021;33006:23;-1:-1:-1;33064:1:1;33058:8;33053:3;33049:18;32957:120;32904:179;:::o;33088:671::-;33127:3;33169:4;33151:16;33148:26;33145:39;;;33088:671;:::o;33145:39::-;33211:2;33205:9;-1:-1:-1;;33276:16:1;33272:25;;33269:1;33205:9;33248:50;33327:4;33321:11;33351:16;-1:-1:-1;;;;;33457:2:1;33450:4;33442:6;33438:17;33435:25;33430:2;33422:6;33419:14;33416:45;33413:58;;;33464:5;;;;;33088:671;:::o;33413:58::-;33501:6;33495:4;33491:17;33480:28;;33537:3;33531:10;33564:2;33556:6;33553:14;33550:27;;;33570:5;;;;;;33088:671;:::o;33550:27::-;33654:2;33635:16;33629:4;33625:27;33621:36;33614:4;33605:6;33600:3;33596:16;33592:27;33589:69;33586:82;;;33661:5;;;;;;33088:671;:::o;33586:82::-;33677:57;33728:4;33719:6;33711;33707:19;33703:30;33697:4;33677:57;:::i;:::-;-1:-1:-1;33750:3:1;;33088:671;-1:-1:-1;;;;;33088:671:1:o;34185:404::-;34387:2;34369:21;;;34426:2;34406:18;;;34399:30;34465:34;34460:2;34445:18;;34438:62;-1:-1:-1;;;34531:2:1;34516:18;;34509:38;34579:3;34564:19;;34185:404::o;35389:827::-;-1:-1:-1;;;;;35786:15:1;;;35768:34;;35838:15;;35833:2;35818:18;;35811:43;35748:3;35885:2;35870:18;;35863:31;;;35711:4;;35917:57;;35954:19;;35946:6;35917:57;:::i;:::-;36022:9;36014:6;36010:22;36005:2;35994:9;35990:18;35983:50;36056:44;36093:6;36085;36056:44;:::i;:::-;36042:58;;36149:9;36141:6;36137:22;36131:3;36120:9;36116:19;36109:51;36177:33;36203:6;36195;36177:33;:::i;:::-;36169:41;35389:827;-1:-1:-1;;;;;;;;35389:827:1:o;36221:127::-;36282:10;36277:3;36273:20;36270:1;36263:31;36313:4;36310:1;36303:15;36337:4;36334:1;36327:15

Swarm Source

ipfs://952fc77d636fde4b39c872c4b89c3a0dc46a83e7b60545a11ce93f434fa86728
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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