OP Sepolia Testnet

Token

ERC20: PCM Test (PCMT)
ERC20

Overview

Max Total Supply

500,000,000 PCMT

Holders

134,923

Market

Price

$0.00 @ 0.000000 ETH

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0.15 PCMT
0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
PCMToken

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 20 : PcmToken.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.22;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "./IPiChainLockable.sol";
import "./Ownerable.sol";

/**
 * @title PCMToken
 * @dev ERC20 token contract representing PiChain Mall with locking mechanisms.
 */
contract PCMToken is ERC20, ERC20Permit, Ownerable {
    address public TREASURY;
    address public CORE_TEAM;
    address public INVESTORS;
    address public SIGN_IN_BONUS;
    address public ADVISORS;
    address public REWARDS;
    address public INITIAL_LIQUIDITY;

    event TransferLiquidity(address indexed preLiquidity, address indexed liquidity);

    constructor(address _owner,address _liquidity,string memory _name, string memory _symbol) ERC20(_name, _symbol) ERC20Permit(_name) {
        transferOwnership(_owner);
        addTransferOwnershipInfo(_owner,86400);
        INITIAL_LIQUIDITY = _liquidity;
    }

    function editOwnerLockedInfo(uint32 _unlockDelaySec) public onlyOwner returns (bool success){
        editTransferOwnershipInfo(_unlockDelaySec);
        success = true;
    }

    function init(address[6] memory addresses) external {
        uint256 _totalAmount = 500_000_000 * 10 ** 18;

        TREASURY = addresses[0];
        CORE_TEAM = addresses[1];
        INVESTORS = addresses[2];
        SIGN_IN_BONUS = addresses[3];
        ADVISORS = addresses[4];
        REWARDS = addresses[5];

        _mint(TREASURY, _totalAmount * 22 / 100);
        _mint(CORE_TEAM, _totalAmount * 20 / 100);
        _mint(INVESTORS, _totalAmount * 4 / 100);
        _mint(SIGN_IN_BONUS, _totalAmount * 6 / 100);
        _mint(INITIAL_LIQUIDITY, _totalAmount * 3 / 100);
        _mint(ADVISORS, _totalAmount * 2 / 100);
        _mint(REWARDS, _totalAmount * 43 / 100);


        for (uint256 i = 0; i < 6; i++) {
            IPiChainLockable(addresses[i]).activate();
        }

        require(totalSupply() == _totalAmount, "PCMToken: InitAmount");
    }

    function transferLiquidity(address _liquidity) public onlyOwner returns (bool success) {
        address _preLiquidity = INITIAL_LIQUIDITY;
        INITIAL_LIQUIDITY = _liquidity;
        emit TransferLiquidity(_preLiquidity, _liquidity);
        success = true;
    }

    /**
     * @dev Unlocks all locked tokens for each role in the ecosystem.
     */
    function unlockAll() external {
        IPiChainLockable(TREASURY).unlock();
        IPiChainLockable(CORE_TEAM).unlock();
        IPiChainLockable(INVESTORS).unlock();
        IPiChainLockable(SIGN_IN_BONUS).unlock();
        IPiChainLockable(ADVISORS).unlock();
        IPiChainLockable(REWARDS).unlock();
    }

}

File 2 of 20 : Ownerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/Context.sol";

/**
 * @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 Ownerable is Context {
    address private _owner;

    mapping(address => TransferOwnerInfo) public infos;

    uint256 transferOwnershipCount = 0 ;

    struct TransferOwnerInfo {
        bool locked; // 锁
        uint32 unlockDelaySec;
        uint48 transferOwnerTime;
    }

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    // owner锁日志
    event TransferOwnerLocked(address indexed account, uint256 unlockDelaySec);
    // owner锁解锁日志
    event TransferOwnerUnlocked(address indexed account, uint256 transferOwnerTime);
    /**
     * @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();
        _;
    }

    // 添加 owner锁信息
    function addTransferOwnershipInfo(address _initOwner,uint32 _initUnlockDelaySec) internal {
        TransferOwnerInfo storage info = infos[_initOwner];
        require(_initUnlockDelaySec >= info.unlockDelaySec, "cannot decrease unlock time");
        infos[_initOwner] = TransferOwnerInfo(
            true,
            _initUnlockDelaySec,
            0
        );
        emit TransferOwnerLocked(_initOwner,_initUnlockDelaySec);
    }

    function editTransferOwnershipInfo(uint32 unlockDelaySec) internal {
        TransferOwnerInfo storage info = infos[msg.sender];
        require(unlockDelaySec >= info.unlockDelaySec, "cannot decrease unlock time");
        infos[msg.sender] = TransferOwnerInfo(
            true,
            unlockDelaySec,
            0
        );
        emit TransferOwnerLocked(msg.sender,unlockDelaySec);
    }
    // 获取 owner锁信息
    function getTransferOwnershipInfo(address account) public view returns (TransferOwnerInfo memory info) {
        return infos[account];
    }
    // owner解锁
    function unlockInfo() external {
        TransferOwnerInfo storage info = infos[msg.sender];
        require(info.unlockDelaySec != 0, "not locked");
        require(info.locked,"already unlocked");
        uint48 transferOwnerTime = uint48(block.timestamp) + info.unlockDelaySec;
        info.transferOwnerTime = transferOwnerTime;
        info.locked = false;
        emit TransferOwnerUnlocked(msg.sender,transferOwnerTime);
    }

    /**
     * @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. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        //_transferOwnership(address(0));
        return;
    }

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

        if (transferOwnershipCount <= 1) {
            _transferOwnership(newOwner);
        } else {
            TransferOwnerInfo storage info = infos[msg.sender];
            require(info.locked == false,"must call unlockInfo() first");
            require(info.transferOwnerTime > 0,"must call unlockInfo() first");
            require(info.transferOwnerTime <= block.timestamp, "Transfer owner is not due");
            _transferOwnership(newOwner);
            addTransferOwnershipInfo(newOwner, info.unlockDelaySec);
        }

    }

    /**
     * @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;
        transferOwnershipCount += 1;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 20 : IPiChainLockable.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.22;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @title IPiChainLockable
 * @dev Interface for a lockable contract with activation and token unlocking functions.
 */
interface IPiChainLockable {
    /**
     * @dev Activate the contract, can only be called once
     */
    function activate() external;

    /**
     * @dev Unlocks the tokens for `beneficiary`.
     */
    function unlock() external;

    /**
     * @dev Returns the amount of tokens unlocked.
     */
    function cumulativeUnlockedAmount() external view returns (uint256);

    /**
     * @dev Emitted when the contract is activated.
     * @param beneficiary The address of the beneficiary.
     * @param amount The amount of tokens to be unlocked.
     */
    event Unlock(address indexed beneficiary, uint256 amount);
}

File 4 of 20 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @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 message) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32")
            mstore(0x1c, hash)
            message := keccak256(0x00, 0x3c)
        }
    }

    /**
     * @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 data) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, "\x19\x01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            data := keccak256(ptr, 0x42)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Data with intended validator, created from a
     * `validator` and `data` according to the version 0 of EIP-191.
     *
     * See {recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x00", validator, data));
    }
}

File 5 of 20 : ERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Permit.sol)

pragma solidity ^0.8.20;

import {IERC20Permit} from "./IERC20Permit.sol";
import {ERC20} from "../ERC20.sol";
import {ECDSA} from "../../../utils/cryptography/ECDSA.sol";
import {EIP712} from "../../../utils/cryptography/EIP712.sol";
import {Nonces} from "../../../utils/Nonces.sol";

/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces {
    bytes32 private constant PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    /**
     * @dev Permit deadline has expired.
     */
    error ERC2612ExpiredSignature(uint256 deadline);

    /**
     * @dev Mismatched signature.
     */
    error ERC2612InvalidSigner(address signer, address owner);

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {}

    /**
     * @inheritdoc IERC20Permit
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        if (block.timestamp > deadline) {
            revert ERC2612ExpiredSignature(deadline);
        }

        bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        if (signer != owner) {
            revert ERC2612InvalidSigner(signer, owner);
        }

        _approve(owner, spender, value);
    }

    /**
     * @inheritdoc IERC20Permit
     */
    function nonces(address owner) public view virtual override(IERC20Permit, Nonces) returns (uint256) {
        return super.nonces(owner);
    }

    /**
     * @inheritdoc IERC20Permit
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view virtual returns (bytes32) {
        return _domainSeparatorV4();
    }
}

File 6 of 20 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

    mapping(address account => mapping(address spender => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     * ```
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}

File 7 of 20 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (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;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 8 of 20 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @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 value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` 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 value) external returns (bool);
}

File 9 of 20 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/Math.sol";
import "./math/SignedMath.sol";

/**
 * @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 `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

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

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 10 of 20 : Nonces.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol)
pragma solidity ^0.8.20;

/**
 * @dev Provides tracking nonces for addresses. Nonces will only increment.
 */
abstract contract Nonces {
    /**
     * @dev The nonce used for an `account` is not the expected current nonce.
     */
    error InvalidAccountNonce(address account, uint256 currentNonce);

    mapping(address account => uint256) private _nonces;

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

    /**
     * @dev Consumes a nonce.
     *
     * Returns the current value and increments nonce.
     */
    function _useNonce(address owner) internal virtual returns (uint256) {
        // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be
        // decremented or reset. This guarantees that the nonce never overflows.
        unchecked {
            // It is important to do x++ and not ++x here.
            return _nonces[owner]++;
        }
    }

    /**
     * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.
     */
    function _useCheckedNonce(address owner, uint256 nonce) internal virtual {
        uint256 current = _useNonce(owner);
        if (nonce != current) {
            revert InvalidAccountNonce(owner, current);
        }
    }
}

File 11 of 20 : EIP712.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.20;

import {MessageHashUtils} from "./MessageHashUtils.sol";
import {ShortStrings, ShortString} from "../ShortStrings.sol";
import {IERC5267} from "../../interfaces/IERC5267.sol";

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose
 * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract
 * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to
 * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
 * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the
 * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
 *
 * @custom:oz-upgrades-unsafe-allow state-variable-immutable
 */
abstract contract EIP712 is IERC5267 {
    using ShortStrings for *;

    bytes32 private constant TYPE_HASH =
        keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _cachedDomainSeparator;
    uint256 private immutable _cachedChainId;
    address private immutable _cachedThis;

    bytes32 private immutable _hashedName;
    bytes32 private immutable _hashedVersion;

    ShortString private immutable _name;
    ShortString private immutable _version;
    string private _nameFallback;
    string private _versionFallback;

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        _name = name.toShortStringWithFallback(_nameFallback);
        _version = version.toShortStringWithFallback(_versionFallback);
        _hashedName = keccak256(bytes(name));
        _hashedVersion = keccak256(bytes(version));

        _cachedChainId = block.chainid;
        _cachedDomainSeparator = _buildDomainSeparator();
        _cachedThis = address(this);
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
            return _cachedDomainSeparator;
        } else {
            return _buildDomainSeparator();
        }
    }

    function _buildDomainSeparator() private view returns (bytes32) {
        return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
    }

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

    /**
     * @dev See {IERC-5267}.
     */
    function eip712Domain()
        public
        view
        virtual
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        return (
            hex"0f", // 01111
            _EIP712Name(),
            _EIP712Version(),
            block.chainid,
            address(this),
            bytes32(0),
            new uint256[](0)
        );
    }

    /**
     * @dev The name parameter for the EIP712 domain.
     *
     * NOTE: By default this function reads _name which is an immutable value.
     * It only reads from storage if necessary (in case the value is too large to fit in a ShortString).
     */
    // solhint-disable-next-line func-name-mixedcase
    function _EIP712Name() internal view returns (string memory) {
        return _name.toStringWithFallback(_nameFallback);
    }

    /**
     * @dev The version parameter for the EIP712 domain.
     *
     * NOTE: By default this function reads _version which is an immutable value.
     * It only reads from storage if necessary (in case the value is too large to fit in a ShortString).
     */
    // solhint-disable-next-line func-name-mixedcase
    function _EIP712Version() internal view returns (string memory) {
        return _version.toStringWithFallback(_versionFallback);
    }
}

File 12 of 20 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

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

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

File 13 of 20 : draft-IERC6093.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

File 14 of 20 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 15 of 20 : IERC5267.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.20;

interface IERC5267 {
    /**
     * @dev MAY be emitted to signal that the domain could have changed.
     */
    event EIP712DomainChanged();

    /**
     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
     * signature.
     */
    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );
}

File 16 of 20 : ShortStrings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol)

pragma solidity ^0.8.8;

import "./StorageSlot.sol";

// | string  | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   |
// | length  | 0x                                                              BB |
type ShortString is bytes32;

/**
 * @dev This library provides functions to convert short memory strings
 * into a `ShortString` type that can be used as an immutable variable.
 *
 * Strings of arbitrary length can be optimized using this library if
 * they are short enough (up to 31 bytes) by packing them with their
 * length (1 byte) in a single EVM word (32 bytes). Additionally, a
 * fallback mechanism can be used for every other case.
 *
 * Usage example:
 *
 * ```solidity
 * contract Named {
 *     using ShortStrings for *;
 *
 *     ShortString private immutable _name;
 *     string private _nameFallback;
 *
 *     constructor(string memory contractName) {
 *         _name = contractName.toShortStringWithFallback(_nameFallback);
 *     }
 *
 *     function name() external view returns (string memory) {
 *         return _name.toStringWithFallback(_nameFallback);
 *     }
 * }
 * ```
 */
library ShortStrings {
    // Used as an identifier for strings longer than 31 bytes.
    bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;

    error StringTooLong(string str);
    error InvalidShortString();

    /**
     * @dev Encode a string of at most 31 chars into a `ShortString`.
     *
     * This will trigger a `StringTooLong` error is the input string is too long.
     */
    function toShortString(string memory str) internal pure returns (ShortString) {
        bytes memory bstr = bytes(str);
        if (bstr.length > 31) {
            revert StringTooLong(str);
        }
        return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));
    }

    /**
     * @dev Decode a `ShortString` back to a "normal" string.
     */
    function toString(ShortString sstr) internal pure returns (string memory) {
        uint256 len = byteLength(sstr);
        // using `new string(len)` would work locally but is not memory safe.
        string memory str = new string(32);
        /// @solidity memory-safe-assembly
        assembly {
            mstore(str, len)
            mstore(add(str, 0x20), sstr)
        }
        return str;
    }

    /**
     * @dev Return the length of a `ShortString`.
     */
    function byteLength(ShortString sstr) internal pure returns (uint256) {
        uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
        if (result > 31) {
            revert InvalidShortString();
        }
        return result;
    }

    /**
     * @dev Encode a string into a `ShortString`, or write it to storage if it is too long.
     */
    function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {
        if (bytes(value).length < 32) {
            return toShortString(value);
        } else {
            StorageSlot.getStringSlot(store).value = value;
            return ShortString.wrap(_FALLBACK_SENTINEL);
        }
    }

    /**
     * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     */
    function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return toString(value);
        } else {
            return store;
        }
    }

    /**
     * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     *
     * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
     * actual characters as the UTF-8 encoding of a single character can span over multiple bytes.
     */
    function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return byteLength(value);
        } else {
            return bytes(store).length;
        }
    }
}

File 17 of 20 : MessageHashUtils.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)

pragma solidity ^0.8.20;

import {Strings} from "../Strings.sol";

/**
 * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.
 *
 * The library provides methods for generating a hash of a message that conforms to the
 * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]
 * specifications.
 */
library MessageHashUtils {
    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x45` (`personal_sign` messages).
     *
     * The digest is calculated by prefixing a bytes32 `messageHash` with
     * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the
     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
     *
     * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with
     * keccak256, although any bytes32 value can be safely used because the final digest will
     * be re-hashed.
     *
     * See {ECDSA-recover}.
     */
    function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash
            mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix
            digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)
        }
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x45` (`personal_sign` messages).
     *
     * The digest is calculated by prefixing an arbitrary `message` with
     * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the
     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
     *
     * See {ECDSA-recover}.
     */
    function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {
        return
            keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message));
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x00` (data with intended validator).
     *
     * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended
     * `validator` address. Then hashing the result.
     *
     * See {ECDSA-recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(hex"19_00", validator, data));
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).
     *
     * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with
     * `\x19\x01` and hashing the result. It corresponds to the hash signed by the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.
     *
     * See {ECDSA-recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, hex"19_01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            digest := keccak256(ptr, 0x42)
        }
    }
}

File 18 of 20 : SignedMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

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

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

File 19 of 20 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 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 256, 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 << 3) < value ? 1 : 0);
        }
    }
}

File 20 of 20 : StorageSlot.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
 * _Available since v4.9 for `string`, `bytes`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "remappings": []
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_liquidity","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ERC2612ExpiredSignature","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC2612InvalidSigner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"currentNonce","type":"uint256"}],"name":"InvalidAccountNonce","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"preLiquidity","type":"address"},{"indexed":true,"internalType":"address","name":"liquidity","type":"address"}],"name":"TransferLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"unlockDelaySec","type":"uint256"}],"name":"TransferOwnerLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"transferOwnerTime","type":"uint256"}],"name":"TransferOwnerUnlocked","type":"event"},{"inputs":[],"name":"ADVISORS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CORE_TEAM","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INITIAL_LIQUIDITY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INVESTORS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARDS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGN_IN_BONUS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_unlockDelaySec","type":"uint32"}],"name":"editOwnerLockedInfo","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getTransferOwnershipInfo","outputs":[{"components":[{"internalType":"bool","name":"locked","type":"bool"},{"internalType":"uint32","name":"unlockDelaySec","type":"uint32"},{"internalType":"uint48","name":"transferOwnerTime","type":"uint48"}],"internalType":"struct Ownerable.TransferOwnerInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"infos","outputs":[{"internalType":"bool","name":"locked","type":"bool"},{"internalType":"uint32","name":"unlockDelaySec","type":"uint32"},{"internalType":"uint48","name":"transferOwnerTime","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[6]","name":"addresses","type":"address[6]"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_liquidity","type":"address"}],"name":"transferLiquidity","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockInfo","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101606040525f600a5534801562000015575f80fd5b5060405162004efb38038062004efb83398181016040528101906200003b919062000a92565b81806040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152508484816003908162000086919062000d76565b50806004908162000098919062000d76565b505050620000b1600583620001dc60201b90919060201c565b6101208181525050620000cf600682620001dc60201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a081815250506200010e6200023160201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250505050506200016c620001606200028d60201b60201c565b6200029460201b60201c565b6200017d846200037260201b60201c565b620001928462015180620005ad60201b60201c565b8260115f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505062001316565b5f6020835110156200020157620001f9836200078060201b60201c565b90506200022b565b826200021383620007ea60201b60201c565b5f01908162000223919062000d76565b5060ff5f1b90505b92915050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e0516101005146306040516020016200027295949392919062000e96565b60405160208183030381529060405280519060200120905090565b5f33905090565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600a5f8282546200030d919062000f1e565b925050819055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b62000382620007f360201b60201c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620003f3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003ea9062000fdc565b60405180910390fd5b6001600a541162000415576200040f816200029460201b60201c565b620005aa565b5f60095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f1515815f015f9054906101000a900460ff16151514620004ad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004a4906200104a565b60405180910390fd5b5f815f0160059054906101000a900465ffffffffffff1665ffffffffffff16116200050f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000506906200104a565b60405180910390fd5b42815f0160059054906101000a900465ffffffffffff1665ffffffffffff16111562000572576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200056990620010b8565b60405180910390fd5b62000583826200029460201b60201c565b620005a882825f0160019054906101000a900463ffffffff16620005ad60201b60201c565b505b50565b5f60095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050805f0160019054906101000a900463ffffffff1663ffffffff168263ffffffff16101562000652576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620006499062001126565b60405180910390fd5b60405180606001604052806001151581526020018363ffffffff1681526020015f65ffffffffffff1681525060095f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160056101000a81548165ffffffffffff021916908365ffffffffffff1602179055509050508273ffffffffffffffffffffffffffffffffffffffff167feb7498540808890de0ea16a2351a51808b1b3a1447a27e20524a6027167747f2836040516200077391906200118d565b60405180910390a2505050565b5f80829050601f81511115620007cf57826040517f305a27a9000000000000000000000000000000000000000000000000000000008152600401620007c69190620011e8565b60405180910390fd5b805181620007dd9062001239565b5f1c175f1b915050919050565b5f819050919050565b620008036200028d60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620008296200088460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000882576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200087990620012f6565b60405180910390fd5b565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620008e882620008bd565b9050919050565b620008fa81620008dc565b811462000905575f80fd5b50565b5f815190506200091881620008ef565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6200096e8262000926565b810181811067ffffffffffffffff8211171562000990576200098f62000936565b5b80604052505050565b5f620009a4620008ac565b9050620009b2828262000963565b919050565b5f67ffffffffffffffff821115620009d457620009d362000936565b5b620009df8262000926565b9050602081019050919050565b5f5b8381101562000a0b578082015181840152602081019050620009ee565b5f8484015250505050565b5f62000a2c62000a2684620009b7565b62000999565b90508281526020810184848401111562000a4b5762000a4a62000922565b5b62000a58848285620009ec565b509392505050565b5f82601f83011262000a775762000a766200091e565b5b815162000a8984826020860162000a16565b91505092915050565b5f805f806080858703121562000aad5762000aac620008b5565b5b5f62000abc8782880162000908565b945050602062000acf8782880162000908565b935050604085015167ffffffffffffffff81111562000af35762000af2620008b9565b5b62000b018782880162000a60565b925050606085015167ffffffffffffffff81111562000b255762000b24620008b9565b5b62000b338782880162000a60565b91505092959194509250565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168062000b8e57607f821691505b60208210810362000ba45762000ba362000b49565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830262000c087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000bcb565b62000c14868362000bcb565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f62000c5e62000c5862000c528462000c2c565b62000c35565b62000c2c565b9050919050565b5f819050919050565b62000c798362000c3e565b62000c9162000c888262000c65565b84845462000bd7565b825550505050565b5f90565b62000ca762000c99565b62000cb481848462000c6e565b505050565b5b8181101562000cdb5762000ccf5f8262000c9d565b60018101905062000cba565b5050565b601f82111562000d2a5762000cf48162000baa565b62000cff8462000bbc565b8101602085101562000d0f578190505b62000d2762000d1e8562000bbc565b83018262000cb9565b50505b505050565b5f82821c905092915050565b5f62000d4c5f198460080262000d2f565b1980831691505092915050565b5f62000d66838362000d3b565b9150826002028217905092915050565b62000d818262000b3f565b67ffffffffffffffff81111562000d9d5762000d9c62000936565b5b62000da9825462000b76565b62000db682828562000cdf565b5f60209050601f83116001811462000dec575f841562000dd7578287015190505b62000de3858262000d59565b86555062000e52565b601f19841662000dfc8662000baa565b5f5b8281101562000e255784890151825560018201915060208501945060208101905062000dfe565b8683101562000e45578489015162000e41601f89168262000d3b565b8355505b6001600288020188555050505b505050505050565b5f819050919050565b62000e6e8162000e5a565b82525050565b62000e7f8162000c2c565b82525050565b62000e9081620008dc565b82525050565b5f60a08201905062000eab5f83018862000e63565b62000eba602083018762000e63565b62000ec9604083018662000e63565b62000ed8606083018562000e74565b62000ee7608083018462000e85565b9695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f62000f2a8262000c2c565b915062000f378362000c2c565b925082820190508082111562000f525762000f5162000ef1565b5b92915050565b5f82825260208201905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f62000fc460268362000f58565b915062000fd18262000f68565b604082019050919050565b5f6020820190508181035f83015262000ff58162000fb6565b9050919050565b7f6d7573742063616c6c20756e6c6f636b496e666f2829206669727374000000005f82015250565b5f62001032601c8362000f58565b91506200103f8262000ffc565b602082019050919050565b5f6020820190508181035f830152620010638162001024565b9050919050565b7f5472616e73666572206f776e6572206973206e6f7420647565000000000000005f82015250565b5f620010a060198362000f58565b9150620010ad826200106a565b602082019050919050565b5f6020820190508181035f830152620010d18162001092565b9050919050565b7f63616e6e6f7420646563726561736520756e6c6f636b2074696d6500000000005f82015250565b5f6200110e601b8362000f58565b91506200111b82620010d8565b602082019050919050565b5f6020820190508181035f8301526200113f8162001100565b9050919050565b5f63ffffffff82169050919050565b5f620011756200116f620011698462001146565b62000c35565b62000c2c565b9050919050565b620011878162001155565b82525050565b5f602082019050620011a25f8301846200117c565b92915050565b5f620011b48262000b3f565b620011c0818562000f58565b9350620011d2818560208601620009ec565b620011dd8162000926565b840191505092915050565b5f6020820190508181035f830152620012028184620011a8565b905092915050565b5f81519050919050565b5f819050602082019050919050565b5f62001230825162000e5a565b80915050919050565b5f62001245826200120a565b82620012518462001214565b90506200125e8162001223565b92506020821015620012a1576200129c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080262000bcb565b831692505b5050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f620012de60208362000f58565b9150620012eb82620012a8565b602082019050919050565b5f6020820190508181035f8301526200130f81620012d0565b9050919050565b60805160a05160c05160e051610100516101205161014051613b93620013685f395f611e8d01525f611e5201525f61262b01525f61260a01525f611d5001525f611da601525f611dcf0152613b935ff3fe608060405234801561000f575f80fd5b50600436106101d8575f3560e01c806370a0823111610102578063a9059cbb116100a0578063cd24b0a31161006f578063cd24b0a314610568578063d505accf14610572578063dd62ed3e1461058e578063f2fde38b146105be576101d8565b8063a9059cbb146104de578063c0034e0c1461050e578063c4a529791461052c578063c6ddb64214610536576101d8565b806384b0196e116100dc57806384b0196e146104605780638da5cb5b1461048457806395d89b41146104a257806399ec816e146104c0576101d8565b806370a08231146103f6578063715018a6146104265780637ecebe0014610430576101d8565b8063242adde31161017a5780633644e515116101495780633644e5151461037e5780634581d3cd1461039c5780634ed87713146103ba57806355097bf1146103d8576101d8565b8063242adde3146102f4578063243a2897146103125780632d2c556514610342578063313ce56714610360576101d8565b80630dfb9d6d116101b65780630dfb9d6d1461025a57806318160ddd1461028a57806321065cdf146102a857806323b872dd146102c4576101d8565b806306fdde03146101dc578063095ea7b3146101fa5780630a0196781461022a575b5f80fd5b6101e46105da565b6040516101f19190612b1d565b60405180910390f35b610214600480360381019061020f9190612bd7565b61066a565b6040516102219190612c2f565b60405180910390f35b610244600480360381019061023f9190612c48565b61068c565b6040516102519190612d00565b60405180910390f35b610274600480360381019061026f9190612c48565b61074c565b6040516102819190612c2f565b60405180910390f35b61029261081e565b60405161029f9190612d28565b60405180910390f35b6102c260048036038101906102bd9190612e6f565b610827565b005b6102de60048036038101906102d99190612e9a565b610cf3565b6040516102eb9190612c2f565b60405180910390f35b6102fc610d21565b6040516103099190612ef9565b60405180910390f35b61032c60048036038101906103279190612f3c565b610d46565b6040516103399190612c2f565b60405180910390f35b61034a610d61565b6040516103579190612ef9565b60405180910390f35b610368610d86565b6040516103759190612f82565b60405180910390f35b610386610d8e565b6040516103939190612fb3565b60405180910390f35b6103a4610d9c565b6040516103b19190612ef9565b60405180910390f35b6103c2610dc1565b6040516103cf9190612ef9565b60405180910390f35b6103e0610de6565b6040516103ed9190612ef9565b60405180910390f35b610410600480360381019061040b9190612c48565b610e0b565b60405161041d9190612d28565b60405180910390f35b61042e610e50565b005b61044a60048036038101906104459190612c48565b610e5a565b6040516104579190612d28565b60405180910390f35b610468610e6b565b60405161047b97969594939291906130bd565b60405180910390f35b61048c610f10565b6040516104999190612ef9565b60405180910390f35b6104aa610f38565b6040516104b79190612b1d565b60405180910390f35b6104c8610fc8565b6040516104d59190612ef9565b60405180910390f35b6104f860048036038101906104f39190612bd7565b610fed565b6040516105059190612c2f565b60405180910390f35b61051661100f565b6040516105239190612ef9565b60405180910390f35b610534611034565b005b610550600480360381019061054b9190612c48565b6111d8565b60405161055f9392919061315d565b60405180910390f35b61057061122a565b005b61058c600480360381019061058791906131e6565b611514565b005b6105a860048036038101906105a39190613283565b611659565b6040516105b59190612d28565b60405180910390f35b6105d860048036038101906105d39190612c48565b6116db565b005b6060600380546105e9906132ee565b80601f0160208091040260200160405190810160405280929190818152602001828054610615906132ee565b80156106605780601f1061063757610100808354040283529160200191610660565b820191905f5260205f20905b81548152906001019060200180831161064357829003601f168201915b5050505050905090565b5f806106746118e8565b90506106818185856118ef565b600191505092915050565b610694612a65565b60095f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900460ff161515151581526020015f820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020015f820160059054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815250509050919050565b5f610755611901565b5f60115f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508260115f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f6429f03bd5306303d1f709406befa7031c811536cade436cf0a330b1c74a8eda60405160405180910390a36001915050919050565b5f600254905090565b5f6b019d971e4fe8401e740000009050815f6006811061084a5761084961331e565b5b6020020151600b5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816001600681106108a2576108a161331e565b5b6020020151600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816002600681106108fa576108f961331e565b5b6020020151600d5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816003600681106109525761095161331e565b5b6020020151600e5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816004600681106109aa576109a961331e565b5b6020020151600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600560068110610a0257610a0161331e565b5b602002015160105f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610a89600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064601684610a7a9190613378565b610a8491906133e6565b61197f565b610acc600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064601484610abd9190613378565b610ac791906133e6565b61197f565b610b0f600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064600484610b009190613378565b610b0a91906133e6565b61197f565b610b52600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064600684610b439190613378565b610b4d91906133e6565b61197f565b610b9560115f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064600384610b869190613378565b610b9091906133e6565b61197f565b610bd8600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064600284610bc99190613378565b610bd391906133e6565b61197f565b610c1b60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064602b84610c0c9190613378565b610c1691906133e6565b61197f565b5f5b6006811015610ca557828160068110610c3957610c3861331e565b5b602002015173ffffffffffffffffffffffffffffffffffffffff16630f15f4c06040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610c82575f80fd5b505af1158015610c94573d5f803e3d5ffd5b505050508080600101915050610c1d565b5080610caf61081e565b14610cef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce690613460565b60405180910390fd5b5050565b5f80610cfd6118e8565b9050610d0a8582856119fe565b610d15858585611a90565b60019150509392505050565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f610d4f611901565b610d5882611b80565b60019050919050565b600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f6012905090565b5f610d97611d4d565b905090565b600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60115f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610e58611901565b565b5f610e6482611e03565b9050919050565b5f6060805f805f6060610e7c611e49565b610e84611e84565b46305f801b5f67ffffffffffffffff811115610ea357610ea2612d45565b5b604051908082528060200260200182016040528015610ed15781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054610f47906132ee565b80601f0160208091040260200160405190810160405280929190818152602001828054610f73906132ee565b8015610fbe5780601f10610f9557610100808354040283529160200191610fbe565b820191905f5260205f20905b815481529060010190602001808311610fa157829003601f168201915b5050505050905090565b600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f80610ff76118e8565b9050611004818585611a90565b600191505092915050565b60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f815f0160019054906101000a900463ffffffff1663ffffffff16036110cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c6906134c8565b60405180910390fd5b805f015f9054906101000a900460ff1661111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111590613530565b60405180910390fd5b5f815f0160019054906101000a900463ffffffff1663ffffffff1642611144919061354e565b905080825f0160056101000a81548165ffffffffffff021916908365ffffffffffff1602179055505f825f015f6101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167f7771292bd4f76abf65cb4edb11cd736aeea5ff907dbafca21cd95e248d8f8a09826040516111cc91906135c0565b60405180910390a25050565b6009602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900463ffffffff1690805f0160059054906101000a900465ffffffffffff16905083565b600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611290575f80fd5b505af11580156112a2573d5f803e3d5ffd5b50505050600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561130c575f80fd5b505af115801561131e573d5f803e3d5ffd5b50505050600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611388575f80fd5b505af115801561139a573d5f803e3d5ffd5b50505050600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611404575f80fd5b505af1158015611416573d5f803e3d5ffd5b50505050600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611480575f80fd5b505af1158015611492573d5f803e3d5ffd5b5050505060105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156114fc575f80fd5b505af115801561150e573d5f803e3d5ffd5b50505050565b8342111561155957836040517f627913020000000000000000000000000000000000000000000000000000000081526004016115509190612d28565b60405180910390fd5b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886115878c611ebf565b8960405160200161159d969594939291906135d9565b6040516020818303038152906040528051906020012090505f6115bf82611f12565b90505f6115ce82878787611f2b565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461164257808a6040517f4b800e46000000000000000000000000000000000000000000000000000000008152600401611639929190613638565b60405180910390fd5b61164d8a8a8a6118ef565b50505050505050505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6116e3611901565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611751576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611748906136cf565b60405180910390fd5b6001600a54116117695761176481611f54565b6118e5565b5f60095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f1515815f015f9054906101000a900460ff161515146117fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f590613737565b60405180910390fd5b5f815f0160059054906101000a900465ffffffffffff1665ffffffffffff161161185d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185490613737565b60405180910390fd5b42815f0160059054906101000a900465ffffffffffff1665ffffffffffff1611156118bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b49061379f565b60405180910390fd5b6118c682611f54565b6118e382825f0160019054906101000a900463ffffffff16612030565b505b50565b5f33905090565b6118fc83838360016121fe565b505050565b6119096118e8565b73ffffffffffffffffffffffffffffffffffffffff16611927610f10565b73ffffffffffffffffffffffffffffffffffffffff161461197d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197490613807565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119ef575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016119e69190612ef9565b60405180910390fd5b6119fa5f83836123cd565b5050565b5f611a098484611659565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611a8a5781811015611a7b578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401611a7293929190613825565b60405180910390fd5b611a8984848484035f6121fe565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611b00575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611af79190612ef9565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b70575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611b679190612ef9565b60405180910390fd5b611b7b8383836123cd565b505050565b5f60095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050805f0160019054906101000a900463ffffffff1663ffffffff168263ffffffff161015611c22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c19906138a4565b60405180910390fd5b60405180606001604052806001151581526020018363ffffffff1681526020015f65ffffffffffff1681525060095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160056101000a81548165ffffffffffff021916908365ffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff167feb7498540808890de0ea16a2351a51808b1b3a1447a27e20524a6027167747f283604051611d4191906138f2565b60405180910390a25050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611dc857507f000000000000000000000000000000000000000000000000000000000000000046145b15611df5577f00000000000000000000000000000000000000000000000000000000000000009050611e00565b611dfd6125e6565b90505b90565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6060611e7f60057f000000000000000000000000000000000000000000000000000000000000000061267b90919063ffffffff16565b905090565b6060611eba60067f000000000000000000000000000000000000000000000000000000000000000061267b90919063ffffffff16565b905090565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815480929190600101919050559050919050565b5f611f24611f1e611d4d565b83612728565b9050919050565b5f805f611f3a87878787612768565b91509150611f4781612840565b8192505050949350505050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600a5f828254611fcb919061390b565b925050819055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f60095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050805f0160019054906101000a900463ffffffff1663ffffffff168263ffffffff1610156120d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c9906138a4565b60405180910390fd5b60405180606001604052806001151581526020018363ffffffff1681526020015f65ffffffffffff1681525060095f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160056101000a81548165ffffffffffff021916908365ffffffffffff1602179055509050508273ffffffffffffffffffffffffffffffffffffffff167feb7498540808890de0ea16a2351a51808b1b3a1447a27e20524a6027167747f2836040516121f191906138f2565b60405180910390a2505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361226e575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016122659190612ef9565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016122d59190612ef9565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156123c7578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516123be9190612d28565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361241d578060025f828254612411919061390b565b925050819055506124eb565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156124a6578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161249d93929190613825565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612532578060025f828254039250508190555061257c565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516125d99190612d28565b60405180910390a3505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000463060405160200161266095949392919061393e565b60405160208183030381529060405280519060200120905090565b606060ff5f1b831461269757612690836129a5565b9050612722565b8180546126a3906132ee565b80601f01602080910402602001604051908101604052809291908181526020018280546126cf906132ee565b801561271a5780601f106126f15761010080835404028352916020019161271a565b820191905f5260205f20905b8154815290600101906020018083116126fd57829003601f168201915b505050505090505b92915050565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0835f1c11156127a0575f600391509150612837565b5f6001878787876040515f81526020016040526040516127c3949392919061398f565b6020604051602081039080840390855afa1580156127e3573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361282f575f60019250925050612837565b805f92509250505b94509492505050565b5f6004811115612853576128526139d2565b5b816004811115612866576128656139d2565b5b03156129a257600160048111156128805761287f6139d2565b5b816004811115612893576128926139d2565b5b036128d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128ca90613a49565b60405180910390fd5b600260048111156128e7576128e66139d2565b5b8160048111156128fa576128f96139d2565b5b0361293a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161293190613ab1565b60405180910390fd5b6003600481111561294e5761294d6139d2565b5b816004811115612961576129606139d2565b5b036129a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299890613b3f565b60405180910390fd5b5b50565b60605f6129b183612a17565b90505f602067ffffffffffffffff8111156129cf576129ce612d45565b5b6040519080825280601f01601f191660200182016040528015612a015781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f8060ff835f1c169050601f811115612a5c576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b60405180606001604052805f151581526020015f63ffffffff1681526020015f65ffffffffffff1681525090565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612aca578082015181840152602081019050612aaf565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612aef82612a93565b612af98185612a9d565b9350612b09818560208601612aad565b612b1281612ad5565b840191505092915050565b5f6020820190508181035f830152612b358184612ae5565b905092915050565b5f604051905090565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612b7382612b4a565b9050919050565b612b8381612b69565b8114612b8d575f80fd5b50565b5f81359050612b9e81612b7a565b92915050565b5f819050919050565b612bb681612ba4565b8114612bc0575f80fd5b50565b5f81359050612bd181612bad565b92915050565b5f8060408385031215612bed57612bec612b46565b5b5f612bfa85828601612b90565b9250506020612c0b85828601612bc3565b9150509250929050565b5f8115159050919050565b612c2981612c15565b82525050565b5f602082019050612c425f830184612c20565b92915050565b5f60208284031215612c5d57612c5c612b46565b5b5f612c6a84828501612b90565b91505092915050565b612c7c81612c15565b82525050565b5f63ffffffff82169050919050565b612c9a81612c82565b82525050565b5f65ffffffffffff82169050919050565b612cba81612ca0565b82525050565b606082015f820151612cd45f850182612c73565b506020820151612ce76020850182612c91565b506040820151612cfa6040850182612cb1565b50505050565b5f606082019050612d135f830184612cc0565b92915050565b612d2281612ba4565b82525050565b5f602082019050612d3b5f830184612d19565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612d7b82612ad5565b810181811067ffffffffffffffff82111715612d9a57612d99612d45565b5b80604052505050565b5f612dac612b3d565b9050612db88282612d72565b919050565b5f67ffffffffffffffff821115612dd757612dd6612d45565b5b602082029050919050565b5f80fd5b5f612df8612df384612dbd565b612da3565b90508060208402830185811115612e1257612e11612de2565b5b835b81811015612e3b5780612e278882612b90565b845260208401935050602081019050612e14565b5050509392505050565b5f82601f830112612e5957612e58612d41565b5b6006612e66848285612de6565b91505092915050565b5f60c08284031215612e8457612e83612b46565b5b5f612e9184828501612e45565b91505092915050565b5f805f60608486031215612eb157612eb0612b46565b5b5f612ebe86828701612b90565b9350506020612ecf86828701612b90565b9250506040612ee086828701612bc3565b9150509250925092565b612ef381612b69565b82525050565b5f602082019050612f0c5f830184612eea565b92915050565b612f1b81612c82565b8114612f25575f80fd5b50565b5f81359050612f3681612f12565b92915050565b5f60208284031215612f5157612f50612b46565b5b5f612f5e84828501612f28565b91505092915050565b5f60ff82169050919050565b612f7c81612f67565b82525050565b5f602082019050612f955f830184612f73565b92915050565b5f819050919050565b612fad81612f9b565b82525050565b5f602082019050612fc65f830184612fa4565b92915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61300081612fcc565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61303881612ba4565b82525050565b5f613049838361302f565b60208301905092915050565b5f602082019050919050565b5f61306b82613006565b6130758185613010565b935061308083613020565b805f5b838110156130b0578151613097888261303e565b97506130a283613055565b925050600181019050613083565b5085935050505092915050565b5f60e0820190506130d05f83018a612ff7565b81810360208301526130e28189612ae5565b905081810360408301526130f68188612ae5565b90506131056060830187612d19565b6131126080830186612eea565b61311f60a0830185612fa4565b81810360c08301526131318184613061565b905098975050505050505050565b61314881612c82565b82525050565b61315781612ca0565b82525050565b5f6060820190506131705f830186612c20565b61317d602083018561313f565b61318a604083018461314e565b949350505050565b61319b81612f67565b81146131a5575f80fd5b50565b5f813590506131b681613192565b92915050565b6131c581612f9b565b81146131cf575f80fd5b50565b5f813590506131e0816131bc565b92915050565b5f805f805f805f60e0888a03121561320157613200612b46565b5b5f61320e8a828b01612b90565b975050602061321f8a828b01612b90565b96505060406132308a828b01612bc3565b95505060606132418a828b01612bc3565b94505060806132528a828b016131a8565b93505060a06132638a828b016131d2565b92505060c06132748a828b016131d2565b91505092959891949750929550565b5f806040838503121561329957613298612b46565b5b5f6132a685828601612b90565b92505060206132b785828601612b90565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061330557607f821691505b602082108103613318576133176132c1565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61338282612ba4565b915061338d83612ba4565b925082820261339b81612ba4565b915082820484148315176133b2576133b161334b565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6133f082612ba4565b91506133fb83612ba4565b92508261340b5761340a6133b9565b5b828204905092915050565b7f50434d546f6b656e3a20496e6974416d6f756e740000000000000000000000005f82015250565b5f61344a601483612a9d565b915061345582613416565b602082019050919050565b5f6020820190508181035f8301526134778161343e565b9050919050565b7f6e6f74206c6f636b6564000000000000000000000000000000000000000000005f82015250565b5f6134b2600a83612a9d565b91506134bd8261347e565b602082019050919050565b5f6020820190508181035f8301526134df816134a6565b9050919050565b7f616c726561647920756e6c6f636b6564000000000000000000000000000000005f82015250565b5f61351a601083612a9d565b9150613525826134e6565b602082019050919050565b5f6020820190508181035f8301526135478161350e565b9050919050565b5f61355882612ca0565b915061356383612ca0565b9250828201905065ffffffffffff8111156135815761358061334b565b5b92915050565b5f819050919050565b5f6135aa6135a56135a084612ca0565b613587565b612ba4565b9050919050565b6135ba81613590565b82525050565b5f6020820190506135d35f8301846135b1565b92915050565b5f60c0820190506135ec5f830189612fa4565b6135f96020830188612eea565b6136066040830187612eea565b6136136060830186612d19565b6136206080830185612d19565b61362d60a0830184612d19565b979650505050505050565b5f60408201905061364b5f830185612eea565b6136586020830184612eea565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6136b9602683612a9d565b91506136c48261365f565b604082019050919050565b5f6020820190508181035f8301526136e6816136ad565b9050919050565b7f6d7573742063616c6c20756e6c6f636b496e666f2829206669727374000000005f82015250565b5f613721601c83612a9d565b915061372c826136ed565b602082019050919050565b5f6020820190508181035f83015261374e81613715565b9050919050565b7f5472616e73666572206f776e6572206973206e6f7420647565000000000000005f82015250565b5f613789601983612a9d565b915061379482613755565b602082019050919050565b5f6020820190508181035f8301526137b68161377d565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f6137f1602083612a9d565b91506137fc826137bd565b602082019050919050565b5f6020820190508181035f83015261381e816137e5565b9050919050565b5f6060820190506138385f830186612eea565b6138456020830185612d19565b6138526040830184612d19565b949350505050565b7f63616e6e6f7420646563726561736520756e6c6f636b2074696d6500000000005f82015250565b5f61388e601b83612a9d565b91506138998261385a565b602082019050919050565b5f6020820190508181035f8301526138bb81613882565b9050919050565b5f6138dc6138d76138d284612c82565b613587565b612ba4565b9050919050565b6138ec816138c2565b82525050565b5f6020820190506139055f8301846138e3565b92915050565b5f61391582612ba4565b915061392083612ba4565b92508282019050808211156139385761393761334b565b5b92915050565b5f60a0820190506139515f830188612fa4565b61395e6020830187612fa4565b61396b6040830186612fa4565b6139786060830185612d19565b6139856080830184612eea565b9695505050505050565b5f6080820190506139a25f830187612fa4565b6139af6020830186612f73565b6139bc6040830185612fa4565b6139c96060830184612fa4565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f45434453413a20696e76616c6964207369676e617475726500000000000000005f82015250565b5f613a33601883612a9d565b9150613a3e826139ff565b602082019050919050565b5f6020820190508181035f830152613a6081613a27565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e677468005f82015250565b5f613a9b601f83612a9d565b9150613aa682613a67565b602082019050919050565b5f6020820190508181035f830152613ac881613a8f565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c5f8201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b5f613b29602283612a9d565b9150613b3482613acf565b604082019050919050565b5f6020820190508181035f830152613b5681613b1d565b905091905056fea2646970667358221220e9aad909b5b22080e9ab9d10fde1dda892127690c5a4297c042c20ff510bf07a64736f6c6343000816003300000000000000000000000036a9ac722158d347738f703db8c40a245c01258e000000000000000000000000e9fc4aaacb4ce8f776255e1af8f9e424dd507bee000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000850434d2054657374000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000450434d5400000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561000f575f80fd5b50600436106101d8575f3560e01c806370a0823111610102578063a9059cbb116100a0578063cd24b0a31161006f578063cd24b0a314610568578063d505accf14610572578063dd62ed3e1461058e578063f2fde38b146105be576101d8565b8063a9059cbb146104de578063c0034e0c1461050e578063c4a529791461052c578063c6ddb64214610536576101d8565b806384b0196e116100dc57806384b0196e146104605780638da5cb5b1461048457806395d89b41146104a257806399ec816e146104c0576101d8565b806370a08231146103f6578063715018a6146104265780637ecebe0014610430576101d8565b8063242adde31161017a5780633644e515116101495780633644e5151461037e5780634581d3cd1461039c5780634ed87713146103ba57806355097bf1146103d8576101d8565b8063242adde3146102f4578063243a2897146103125780632d2c556514610342578063313ce56714610360576101d8565b80630dfb9d6d116101b65780630dfb9d6d1461025a57806318160ddd1461028a57806321065cdf146102a857806323b872dd146102c4576101d8565b806306fdde03146101dc578063095ea7b3146101fa5780630a0196781461022a575b5f80fd5b6101e46105da565b6040516101f19190612b1d565b60405180910390f35b610214600480360381019061020f9190612bd7565b61066a565b6040516102219190612c2f565b60405180910390f35b610244600480360381019061023f9190612c48565b61068c565b6040516102519190612d00565b60405180910390f35b610274600480360381019061026f9190612c48565b61074c565b6040516102819190612c2f565b60405180910390f35b61029261081e565b60405161029f9190612d28565b60405180910390f35b6102c260048036038101906102bd9190612e6f565b610827565b005b6102de60048036038101906102d99190612e9a565b610cf3565b6040516102eb9190612c2f565b60405180910390f35b6102fc610d21565b6040516103099190612ef9565b60405180910390f35b61032c60048036038101906103279190612f3c565b610d46565b6040516103399190612c2f565b60405180910390f35b61034a610d61565b6040516103579190612ef9565b60405180910390f35b610368610d86565b6040516103759190612f82565b60405180910390f35b610386610d8e565b6040516103939190612fb3565b60405180910390f35b6103a4610d9c565b6040516103b19190612ef9565b60405180910390f35b6103c2610dc1565b6040516103cf9190612ef9565b60405180910390f35b6103e0610de6565b6040516103ed9190612ef9565b60405180910390f35b610410600480360381019061040b9190612c48565b610e0b565b60405161041d9190612d28565b60405180910390f35b61042e610e50565b005b61044a60048036038101906104459190612c48565b610e5a565b6040516104579190612d28565b60405180910390f35b610468610e6b565b60405161047b97969594939291906130bd565b60405180910390f35b61048c610f10565b6040516104999190612ef9565b60405180910390f35b6104aa610f38565b6040516104b79190612b1d565b60405180910390f35b6104c8610fc8565b6040516104d59190612ef9565b60405180910390f35b6104f860048036038101906104f39190612bd7565b610fed565b6040516105059190612c2f565b60405180910390f35b61051661100f565b6040516105239190612ef9565b60405180910390f35b610534611034565b005b610550600480360381019061054b9190612c48565b6111d8565b60405161055f9392919061315d565b60405180910390f35b61057061122a565b005b61058c600480360381019061058791906131e6565b611514565b005b6105a860048036038101906105a39190613283565b611659565b6040516105b59190612d28565b60405180910390f35b6105d860048036038101906105d39190612c48565b6116db565b005b6060600380546105e9906132ee565b80601f0160208091040260200160405190810160405280929190818152602001828054610615906132ee565b80156106605780601f1061063757610100808354040283529160200191610660565b820191905f5260205f20905b81548152906001019060200180831161064357829003601f168201915b5050505050905090565b5f806106746118e8565b90506106818185856118ef565b600191505092915050565b610694612a65565b60095f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206040518060600160405290815f82015f9054906101000a900460ff161515151581526020015f820160019054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020015f820160059054906101000a900465ffffffffffff1665ffffffffffff1665ffffffffffff16815250509050919050565b5f610755611901565b5f60115f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508260115f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f6429f03bd5306303d1f709406befa7031c811536cade436cf0a330b1c74a8eda60405160405180910390a36001915050919050565b5f600254905090565b5f6b019d971e4fe8401e740000009050815f6006811061084a5761084961331e565b5b6020020151600b5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816001600681106108a2576108a161331e565b5b6020020151600c5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816002600681106108fa576108f961331e565b5b6020020151600d5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816003600681106109525761095161331e565b5b6020020151600e5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816004600681106109aa576109a961331e565b5b6020020151600f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600560068110610a0257610a0161331e565b5b602002015160105f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610a89600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064601684610a7a9190613378565b610a8491906133e6565b61197f565b610acc600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064601484610abd9190613378565b610ac791906133e6565b61197f565b610b0f600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064600484610b009190613378565b610b0a91906133e6565b61197f565b610b52600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064600684610b439190613378565b610b4d91906133e6565b61197f565b610b9560115f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064600384610b869190613378565b610b9091906133e6565b61197f565b610bd8600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064600284610bc99190613378565b610bd391906133e6565b61197f565b610c1b60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166064602b84610c0c9190613378565b610c1691906133e6565b61197f565b5f5b6006811015610ca557828160068110610c3957610c3861331e565b5b602002015173ffffffffffffffffffffffffffffffffffffffff16630f15f4c06040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610c82575f80fd5b505af1158015610c94573d5f803e3d5ffd5b505050508080600101915050610c1d565b5080610caf61081e565b14610cef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce690613460565b60405180910390fd5b5050565b5f80610cfd6118e8565b9050610d0a8582856119fe565b610d15858585611a90565b60019150509392505050565b600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f610d4f611901565b610d5882611b80565b60019050919050565b600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f6012905090565b5f610d97611d4d565b905090565b600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60115f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610e58611901565b565b5f610e6482611e03565b9050919050565b5f6060805f805f6060610e7c611e49565b610e84611e84565b46305f801b5f67ffffffffffffffff811115610ea357610ea2612d45565b5b604051908082528060200260200182016040528015610ed15781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054610f47906132ee565b80601f0160208091040260200160405190810160405280929190818152602001828054610f73906132ee565b8015610fbe5780601f10610f9557610100808354040283529160200191610fbe565b820191905f5260205f20905b815481529060010190602001808311610fa157829003601f168201915b5050505050905090565b600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f80610ff76118e8565b9050611004818585611a90565b600191505092915050565b60105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f815f0160019054906101000a900463ffffffff1663ffffffff16036110cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c6906134c8565b60405180910390fd5b805f015f9054906101000a900460ff1661111e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111590613530565b60405180910390fd5b5f815f0160019054906101000a900463ffffffff1663ffffffff1642611144919061354e565b905080825f0160056101000a81548165ffffffffffff021916908365ffffffffffff1602179055505f825f015f6101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167f7771292bd4f76abf65cb4edb11cd736aeea5ff907dbafca21cd95e248d8f8a09826040516111cc91906135c0565b60405180910390a25050565b6009602052805f5260405f205f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900463ffffffff1690805f0160059054906101000a900465ffffffffffff16905083565b600b5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611290575f80fd5b505af11580156112a2573d5f803e3d5ffd5b50505050600c5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561130c575f80fd5b505af115801561131e573d5f803e3d5ffd5b50505050600d5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611388575f80fd5b505af115801561139a573d5f803e3d5ffd5b50505050600e5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611404575f80fd5b505af1158015611416573d5f803e3d5ffd5b50505050600f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611480575f80fd5b505af1158015611492573d5f803e3d5ffd5b5050505060105f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a69df4b56040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156114fc575f80fd5b505af115801561150e573d5f803e3d5ffd5b50505050565b8342111561155957836040517f627913020000000000000000000000000000000000000000000000000000000081526004016115509190612d28565b60405180910390fd5b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886115878c611ebf565b8960405160200161159d969594939291906135d9565b6040516020818303038152906040528051906020012090505f6115bf82611f12565b90505f6115ce82878787611f2b565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461164257808a6040517f4b800e46000000000000000000000000000000000000000000000000000000008152600401611639929190613638565b60405180910390fd5b61164d8a8a8a6118ef565b50505050505050505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6116e3611901565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611751576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611748906136cf565b60405180910390fd5b6001600a54116117695761176481611f54565b6118e5565b5f60095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2090505f1515815f015f9054906101000a900460ff161515146117fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f590613737565b60405180910390fd5b5f815f0160059054906101000a900465ffffffffffff1665ffffffffffff161161185d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185490613737565b60405180910390fd5b42815f0160059054906101000a900465ffffffffffff1665ffffffffffff1611156118bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b49061379f565b60405180910390fd5b6118c682611f54565b6118e382825f0160019054906101000a900463ffffffff16612030565b505b50565b5f33905090565b6118fc83838360016121fe565b505050565b6119096118e8565b73ffffffffffffffffffffffffffffffffffffffff16611927610f10565b73ffffffffffffffffffffffffffffffffffffffff161461197d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197490613807565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036119ef575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016119e69190612ef9565b60405180910390fd5b6119fa5f83836123cd565b5050565b5f611a098484611659565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611a8a5781811015611a7b578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401611a7293929190613825565b60405180910390fd5b611a8984848484035f6121fe565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611b00575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611af79190612ef9565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b70575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611b679190612ef9565b60405180910390fd5b611b7b8383836123cd565b505050565b5f60095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050805f0160019054906101000a900463ffffffff1663ffffffff168263ffffffff161015611c22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c19906138a4565b60405180910390fd5b60405180606001604052806001151581526020018363ffffffff1681526020015f65ffffffffffff1681525060095f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160056101000a81548165ffffffffffff021916908365ffffffffffff1602179055509050503373ffffffffffffffffffffffffffffffffffffffff167feb7498540808890de0ea16a2351a51808b1b3a1447a27e20524a6027167747f283604051611d4191906138f2565b60405180910390a25050565b5f7f0000000000000000000000006926fbff41d234afe0ad2f1c73558afa83d8d8ae73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611dc857507f0000000000000000000000000000000000000000000000000000000000aa37dc46145b15611df5577fb5706615afb00d63fb72b8a4cdc7ce182625e432671686fdbd2dfb7416583db49050611e00565b611dfd6125e6565b90505b90565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6060611e7f60057f50434d205465737400000000000000000000000000000000000000000000000861267b90919063ffffffff16565b905090565b6060611eba60067f310000000000000000000000000000000000000000000000000000000000000161267b90919063ffffffff16565b905090565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815480929190600101919050559050919050565b5f611f24611f1e611d4d565b83612728565b9050919050565b5f805f611f3a87878787612768565b91509150611f4781612840565b8192505050949350505050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600a5f828254611fcb919061390b565b925050819055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f60095f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f209050805f0160019054906101000a900463ffffffff1663ffffffff168263ffffffff1610156120d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c9906138a4565b60405180910390fd5b60405180606001604052806001151581526020018363ffffffff1681526020015f65ffffffffffff1681525060095f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548163ffffffff021916908363ffffffff1602179055506040820151815f0160056101000a81548165ffffffffffff021916908365ffffffffffff1602179055509050508273ffffffffffffffffffffffffffffffffffffffff167feb7498540808890de0ea16a2351a51808b1b3a1447a27e20524a6027167747f2836040516121f191906138f2565b60405180910390a2505050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361226e575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016122659190612ef9565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036122de575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016122d59190612ef9565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156123c7578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516123be9190612d28565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361241d578060025f828254612411919061390b565b925050819055506124eb565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156124a6578381836040517fe450d38c00000000000000000000000000000000000000000000000000000000815260040161249d93929190613825565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612532578060025f828254039250508190555061257c565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516125d99190612d28565b60405180910390a3505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f95fe00177ce8d12f3f8e46f0a763f07b6c04bed4a86e7ca9ac0aec17495cd4ee7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6463060405160200161266095949392919061393e565b60405160208183030381529060405280519060200120905090565b606060ff5f1b831461269757612690836129a5565b9050612722565b8180546126a3906132ee565b80601f01602080910402602001604051908101604052809291908181526020018280546126cf906132ee565b801561271a5780601f106126f15761010080835404028352916020019161271a565b820191905f5260205f20905b8154815290600101906020018083116126fd57829003601f168201915b505050505090505b92915050565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0835f1c11156127a0575f600391509150612837565b5f6001878787876040515f81526020016040526040516127c3949392919061398f565b6020604051602081039080840390855afa1580156127e3573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361282f575f60019250925050612837565b805f92509250505b94509492505050565b5f6004811115612853576128526139d2565b5b816004811115612866576128656139d2565b5b03156129a257600160048111156128805761287f6139d2565b5b816004811115612893576128926139d2565b5b036128d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128ca90613a49565b60405180910390fd5b600260048111156128e7576128e66139d2565b5b8160048111156128fa576128f96139d2565b5b0361293a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161293190613ab1565b60405180910390fd5b6003600481111561294e5761294d6139d2565b5b816004811115612961576129606139d2565b5b036129a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299890613b3f565b60405180910390fd5b5b50565b60605f6129b183612a17565b90505f602067ffffffffffffffff8111156129cf576129ce612d45565b5b6040519080825280601f01601f191660200182016040528015612a015781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f8060ff835f1c169050601f811115612a5c576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b60405180606001604052805f151581526020015f63ffffffff1681526020015f65ffffffffffff1681525090565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015612aca578082015181840152602081019050612aaf565b5f8484015250505050565b5f601f19601f8301169050919050565b5f612aef82612a93565b612af98185612a9d565b9350612b09818560208601612aad565b612b1281612ad5565b840191505092915050565b5f6020820190508181035f830152612b358184612ae5565b905092915050565b5f604051905090565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612b7382612b4a565b9050919050565b612b8381612b69565b8114612b8d575f80fd5b50565b5f81359050612b9e81612b7a565b92915050565b5f819050919050565b612bb681612ba4565b8114612bc0575f80fd5b50565b5f81359050612bd181612bad565b92915050565b5f8060408385031215612bed57612bec612b46565b5b5f612bfa85828601612b90565b9250506020612c0b85828601612bc3565b9150509250929050565b5f8115159050919050565b612c2981612c15565b82525050565b5f602082019050612c425f830184612c20565b92915050565b5f60208284031215612c5d57612c5c612b46565b5b5f612c6a84828501612b90565b91505092915050565b612c7c81612c15565b82525050565b5f63ffffffff82169050919050565b612c9a81612c82565b82525050565b5f65ffffffffffff82169050919050565b612cba81612ca0565b82525050565b606082015f820151612cd45f850182612c73565b506020820151612ce76020850182612c91565b506040820151612cfa6040850182612cb1565b50505050565b5f606082019050612d135f830184612cc0565b92915050565b612d2281612ba4565b82525050565b5f602082019050612d3b5f830184612d19565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612d7b82612ad5565b810181811067ffffffffffffffff82111715612d9a57612d99612d45565b5b80604052505050565b5f612dac612b3d565b9050612db88282612d72565b919050565b5f67ffffffffffffffff821115612dd757612dd6612d45565b5b602082029050919050565b5f80fd5b5f612df8612df384612dbd565b612da3565b90508060208402830185811115612e1257612e11612de2565b5b835b81811015612e3b5780612e278882612b90565b845260208401935050602081019050612e14565b5050509392505050565b5f82601f830112612e5957612e58612d41565b5b6006612e66848285612de6565b91505092915050565b5f60c08284031215612e8457612e83612b46565b5b5f612e9184828501612e45565b91505092915050565b5f805f60608486031215612eb157612eb0612b46565b5b5f612ebe86828701612b90565b9350506020612ecf86828701612b90565b9250506040612ee086828701612bc3565b9150509250925092565b612ef381612b69565b82525050565b5f602082019050612f0c5f830184612eea565b92915050565b612f1b81612c82565b8114612f25575f80fd5b50565b5f81359050612f3681612f12565b92915050565b5f60208284031215612f5157612f50612b46565b5b5f612f5e84828501612f28565b91505092915050565b5f60ff82169050919050565b612f7c81612f67565b82525050565b5f602082019050612f955f830184612f73565b92915050565b5f819050919050565b612fad81612f9b565b82525050565b5f602082019050612fc65f830184612fa4565b92915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61300081612fcc565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61303881612ba4565b82525050565b5f613049838361302f565b60208301905092915050565b5f602082019050919050565b5f61306b82613006565b6130758185613010565b935061308083613020565b805f5b838110156130b0578151613097888261303e565b97506130a283613055565b925050600181019050613083565b5085935050505092915050565b5f60e0820190506130d05f83018a612ff7565b81810360208301526130e28189612ae5565b905081810360408301526130f68188612ae5565b90506131056060830187612d19565b6131126080830186612eea565b61311f60a0830185612fa4565b81810360c08301526131318184613061565b905098975050505050505050565b61314881612c82565b82525050565b61315781612ca0565b82525050565b5f6060820190506131705f830186612c20565b61317d602083018561313f565b61318a604083018461314e565b949350505050565b61319b81612f67565b81146131a5575f80fd5b50565b5f813590506131b681613192565b92915050565b6131c581612f9b565b81146131cf575f80fd5b50565b5f813590506131e0816131bc565b92915050565b5f805f805f805f60e0888a03121561320157613200612b46565b5b5f61320e8a828b01612b90565b975050602061321f8a828b01612b90565b96505060406132308a828b01612bc3565b95505060606132418a828b01612bc3565b94505060806132528a828b016131a8565b93505060a06132638a828b016131d2565b92505060c06132748a828b016131d2565b91505092959891949750929550565b5f806040838503121561329957613298612b46565b5b5f6132a685828601612b90565b92505060206132b785828601612b90565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061330557607f821691505b602082108103613318576133176132c1565b5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61338282612ba4565b915061338d83612ba4565b925082820261339b81612ba4565b915082820484148315176133b2576133b161334b565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6133f082612ba4565b91506133fb83612ba4565b92508261340b5761340a6133b9565b5b828204905092915050565b7f50434d546f6b656e3a20496e6974416d6f756e740000000000000000000000005f82015250565b5f61344a601483612a9d565b915061345582613416565b602082019050919050565b5f6020820190508181035f8301526134778161343e565b9050919050565b7f6e6f74206c6f636b6564000000000000000000000000000000000000000000005f82015250565b5f6134b2600a83612a9d565b91506134bd8261347e565b602082019050919050565b5f6020820190508181035f8301526134df816134a6565b9050919050565b7f616c726561647920756e6c6f636b6564000000000000000000000000000000005f82015250565b5f61351a601083612a9d565b9150613525826134e6565b602082019050919050565b5f6020820190508181035f8301526135478161350e565b9050919050565b5f61355882612ca0565b915061356383612ca0565b9250828201905065ffffffffffff8111156135815761358061334b565b5b92915050565b5f819050919050565b5f6135aa6135a56135a084612ca0565b613587565b612ba4565b9050919050565b6135ba81613590565b82525050565b5f6020820190506135d35f8301846135b1565b92915050565b5f60c0820190506135ec5f830189612fa4565b6135f96020830188612eea565b6136066040830187612eea565b6136136060830186612d19565b6136206080830185612d19565b61362d60a0830184612d19565b979650505050505050565b5f60408201905061364b5f830185612eea565b6136586020830184612eea565b9392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6136b9602683612a9d565b91506136c48261365f565b604082019050919050565b5f6020820190508181035f8301526136e6816136ad565b9050919050565b7f6d7573742063616c6c20756e6c6f636b496e666f2829206669727374000000005f82015250565b5f613721601c83612a9d565b915061372c826136ed565b602082019050919050565b5f6020820190508181035f83015261374e81613715565b9050919050565b7f5472616e73666572206f776e6572206973206e6f7420647565000000000000005f82015250565b5f613789601983612a9d565b915061379482613755565b602082019050919050565b5f6020820190508181035f8301526137b68161377d565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65725f82015250565b5f6137f1602083612a9d565b91506137fc826137bd565b602082019050919050565b5f6020820190508181035f83015261381e816137e5565b9050919050565b5f6060820190506138385f830186612eea565b6138456020830185612d19565b6138526040830184612d19565b949350505050565b7f63616e6e6f7420646563726561736520756e6c6f636b2074696d6500000000005f82015250565b5f61388e601b83612a9d565b91506138998261385a565b602082019050919050565b5f6020820190508181035f8301526138bb81613882565b9050919050565b5f6138dc6138d76138d284612c82565b613587565b612ba4565b9050919050565b6138ec816138c2565b82525050565b5f6020820190506139055f8301846138e3565b92915050565b5f61391582612ba4565b915061392083612ba4565b92508282019050808211156139385761393761334b565b5b92915050565b5f60a0820190506139515f830188612fa4565b61395e6020830187612fa4565b61396b6040830186612fa4565b6139786060830185612d19565b6139856080830184612eea565b9695505050505050565b5f6080820190506139a25f830187612fa4565b6139af6020830186612f73565b6139bc6040830185612fa4565b6139c96060830184612fa4565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f45434453413a20696e76616c6964207369676e617475726500000000000000005f82015250565b5f613a33601883612a9d565b9150613a3e826139ff565b602082019050919050565b5f6020820190508181035f830152613a6081613a27565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e677468005f82015250565b5f613a9b601f83612a9d565b9150613aa682613a67565b602082019050919050565b5f6020820190508181035f830152613ac881613a8f565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c5f8201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b5f613b29602283612a9d565b9150613b3482613acf565b604082019050919050565b5f6020820190508181035f830152613b5681613b1d565b905091905056fea2646970667358221220e9aad909b5b22080e9ab9d10fde1dda892127690c5a4297c042c20ff510bf07a64736f6c63430008160033

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

00000000000000000000000036a9ac722158d347738f703db8c40a245c01258e000000000000000000000000e9fc4aaacb4ce8f776255e1af8f9e424dd507bee000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000850434d2054657374000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000450434d5400000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _owner (address): 0x36a9AC722158D347738f703Db8c40A245C01258e
Arg [1] : _liquidity (address): 0xe9Fc4AaaCb4ce8f776255e1af8F9E424dD507beE
Arg [2] : _name (string): PCM Test
Arg [3] : _symbol (string): PCMT

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 00000000000000000000000036a9ac722158d347738f703db8c40a245c01258e
Arg [1] : 000000000000000000000000e9fc4aaacb4ce8f776255e1af8f9e424dd507bee
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [5] : 50434d2054657374000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 50434d5400000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

433:2423:19:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2074:89:2;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4293:186;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2510:143:18;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2161:273:19;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3144:97:2;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1266:887:19;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5039:244:2;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;521:24:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1080:178;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;491:23;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3002:82:2;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2656:112:4;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;552:24:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;618:23;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;677:32;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3299:116:2;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3842:122:18;;;:::i;:::-;;2406:143:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5144:557:13;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;3201:87:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2276:93:2;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;583:28:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3610:178:2;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;648:22:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2679:441:18;;;:::i;:::-;;701:50;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;2531:320:19;;;:::i;:::-;;1680:672:4;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3846:140:2;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4119:710:18;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;2074:89:2;2119:13;2151:5;2144:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2074:89;:::o;4293:186::-;4366:4;4382:13;4398:12;:10;:12::i;:::-;4382:28;;4420:31;4429:5;4436:7;4445:5;4420:8;:31::i;:::-;4468:4;4461:11;;;4293:186;;;;:::o;2510:143:18:-;2582:29;;:::i;:::-;2631:5;:14;2637:7;2631:14;;;;;;;;;;;;;;;2624:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2510:143;;;:::o;2161:273:19:-;2234:12;1539:13:18;:11;:13::i;:::-;2259:21:19::1;2283:17;;;;;;;;;;;2259:41;;2331:10;2311:17;;:30;;;;;;;;;;;;;;;;;;2390:10;2357:44;;2375:13;2357:44;;;;;;;;;;;;2422:4;2412:14;;2248:186;2161:273:::0;;;:::o;3144:97:2:-;3196:7;3222:12;;3215:19;;3144:97;:::o;1266:887:19:-;1329:20;1352:22;1329:45;;1398:9;1408:1;1398:12;;;;;;;:::i;:::-;;;;;;1387:8;;:23;;;;;;;;;;;;;;;;;;1433:9;1443:1;1433:12;;;;;;;:::i;:::-;;;;;;1421:9;;:24;;;;;;;;;;;;;;;;;;1468:9;1478:1;1468:12;;;;;;;:::i;:::-;;;;;;1456:9;;:24;;;;;;;;;;;;;;;;;;1507:9;1517:1;1507:12;;;;;;;:::i;:::-;;;;;;1491:13;;:28;;;;;;;;;;;;;;;;;;1541:9;1551:1;1541:12;;;;;;;:::i;:::-;;;;;;1530:8;;:23;;;;;;;;;;;;;;;;;;1574:9;1584:1;1574:12;;;;;;;:::i;:::-;;;;;;1564:7;;:22;;;;;;;;;;;;;;;;;;1599:40;1605:8;;;;;;;;;;;1635:3;1630:2;1615:12;:17;;;;:::i;:::-;:23;;;;:::i;:::-;1599:5;:40::i;:::-;1650:41;1656:9;;;;;;;;;;;1687:3;1682:2;1667:12;:17;;;;:::i;:::-;:23;;;;:::i;:::-;1650:5;:41::i;:::-;1702:40;1708:9;;;;;;;;;;;1738:3;1734:1;1719:12;:16;;;;:::i;:::-;:22;;;;:::i;:::-;1702:5;:40::i;:::-;1753:44;1759:13;;;;;;;;;;;1793:3;1789:1;1774:12;:16;;;;:::i;:::-;:22;;;;:::i;:::-;1753:5;:44::i;:::-;1808:48;1814:17;;;;;;;;;;;1852:3;1848:1;1833:12;:16;;;;:::i;:::-;:22;;;;:::i;:::-;1808:5;:48::i;:::-;1867:39;1873:8;;;;;;;;;;;1902:3;1898:1;1883:12;:16;;;;:::i;:::-;:22;;;;:::i;:::-;1867:5;:39::i;:::-;1917;1923:7;;;;;;;;;;;1952:3;1947:2;1932:12;:17;;;;:::i;:::-;:23;;;;:::i;:::-;1917:5;:39::i;:::-;1976:9;1971:100;1995:1;1991;:5;1971:100;;;2035:9;2045:1;2035:12;;;;;;;:::i;:::-;;;;;;2018:39;;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1998:3;;;;;;;1971:100;;;;2108:12;2091:13;:11;:13::i;:::-;:29;2083:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;1318:835;1266:887;:::o;5039:244:2:-;5126:4;5142:15;5160:12;:10;:12::i;:::-;5142:30;;5182:37;5198:4;5204:7;5213:5;5182:15;:37::i;:::-;5229:26;5239:4;5245:2;5249:5;5229:9;:26::i;:::-;5272:4;5265:11;;;5039:244;;;;;:::o;521:24:19:-;;;;;;;;;;;;;:::o;1080:178::-;1159:12;1539:13:18;:11;:13::i;:::-;1183:42:19::1;1209:15;1183:25;:42::i;:::-;1246:4;1236:14;;1080:178:::0;;;:::o;491:23::-;;;;;;;;;;;;;:::o;3002:82:2:-;3051:5;3075:2;3068:9;;3002:82;:::o;2656:112:4:-;2715:7;2741:20;:18;:20::i;:::-;2734:27;;2656:112;:::o;552:24:19:-;;;;;;;;;;;;;:::o;618:23::-;;;;;;;;;;;;;:::o;677:32::-;;;;;;;;;;;;;:::o;3299:116:2:-;3364:7;3390:9;:18;3400:7;3390:18;;;;;;;;;;;;;;;;3383:25;;3299:116;;;:::o;3842:122:18:-;1539:13;:11;:13::i;:::-;3842:122::o;2406:143:4:-;2497:7;2523:19;2536:5;2523:12;:19::i;:::-;2516:26;;2406:143;;;:::o;5144:557:13:-;5242:13;5269:18;5301:21;5336:15;5365:25;5404:12;5430:27;5533:13;:11;:13::i;:::-;5560:16;:14;:16::i;:::-;5590:13;5625:4;5652:1;5644:10;;5682:1;5668:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5482:212;;;;;;;;;;;;;;;;;;;;;5144:557;;;;;;;:::o;3201:87:18:-;3247:7;3274:6;;;;;;;;;;;3267:13;;3201:87;:::o;2276:93:2:-;2323:13;2355:7;2348:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2276:93;:::o;583:28:19:-;;;;;;;;;;;;;:::o;3610:178:2:-;3679:4;3695:13;3711:12;:10;:12::i;:::-;3695:28;;3733:27;3743:5;3750:2;3754:5;3733:9;:27::i;:::-;3777:4;3770:11;;;3610:178;;;;:::o;648:22:19:-;;;;;;;;;;;;;:::o;2679:441:18:-;2721:30;2754:5;:17;2760:10;2754:17;;;;;;;;;;;;;;;2721:50;;2813:1;2790:4;:19;;;;;;;;;;;;:24;;;2782:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;2848:4;:11;;;;;;;;;;;;2840:39;;;;;;;;;;;;:::i;:::-;;;;;;;;;2890:24;2943:4;:19;;;;;;;;;;;;2917:45;;2924:15;2917:45;;;;:::i;:::-;2890:72;;2998:17;2973:4;:22;;;:42;;;;;;;;;;;;;;;;;;3040:5;3026:4;:11;;;:19;;;;;;;;;;;;;;;;;;3083:10;3061:51;;;3094:17;3061:51;;;;;;:::i;:::-;;;;;;;;2710:410;;2679:441::o;701:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2531:320:19:-;2589:8;;;;;;;;;;;2572:33;;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2635:9;;;;;;;;;;;2618:34;;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2682:9;;;;;;;;;;;2665:34;;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2729:13;;;;;;;;;;;2712:38;;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2780:8;;;;;;;;;;;2763:33;;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2826:7;;;;;;;;;;;2809:32;;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2531:320::o;1680:672:4:-;1901:8;1883:15;:26;1879:97;;;1956:8;1932:33;;;;;;;;;;;:::i;:::-;;;;;;;;1879:97;1986:18;1022:95;2045:5;2052:7;2061:5;2068:16;2078:5;2068:9;:16::i;:::-;2086:8;2017:78;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;2007:89;;;;;;1986:110;;2107:12;2122:28;2139:10;2122:16;:28::i;:::-;2107:43;;2161:14;2178:28;2192:4;2198:1;2201;2204;2178:13;:28::i;:::-;2161:45;;2230:5;2220:15;;:6;:15;;;2216:88;;2279:6;2287:5;2258:35;;;;;;;;;;;;:::i;:::-;;;;;;;;2216:88;2314:31;2323:5;2330:7;2339:5;2314:8;:31::i;:::-;1869:483;;;1680:672;;;;;;;:::o;3846:140:2:-;3926:7;3952:11;:18;3964:5;3952:18;;;;;;;;;;;;;;;:27;3971:7;3952:27;;;;;;;;;;;;;;;;3945:34;;3846:140;;;;:::o;4119:710:18:-;1539:13;:11;:13::i;:::-;4228:1:::1;4208:22;;:8;:22;;::::0;4200:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;4316:1;4290:22;;:27;4286:534;;4334:28;4353:8;4334:18;:28::i;:::-;4286:534;;;4395:30;4428:5;:17;4434:10;4428:17;;;;;;;;;;;;;;;4395:50;;4483:5;4468:20;;:4;:11;;;;;;;;;;;;:20;;;4460:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;4568:1;4543:4;:22;;;;;;;;;;;;:26;;;4535:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;4650:15;4624:4;:22;;;;;;;;;;;;:41;;;;4616:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;4710:28;4729:8;4710:18;:28::i;:::-;4753:55;4778:8;4788:4;:19;;;;;;;;;;;;4753:24;:55::i;:::-;4380:440;4286:534;4119:710:::0;:::o;655:96:7:-;708:7;734:10;727:17;;655:96;:::o;8989:128:2:-;9073:37;9082:5;9089:7;9098:5;9105:4;9073:8;:37::i;:::-;8989:128;;;:::o;3366:132:18:-;3441:12;:10;:12::i;:::-;3430:23;;:7;:5;:7::i;:::-;:23;;;3422:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;3366:132::o;7721:208:2:-;7810:1;7791:21;;:7;:21;;;7787:91;;7864:1;7835:32;;;;;;;;;;;:::i;:::-;;;;;;;;7787:91;7887:35;7903:1;7907:7;7916:5;7887:7;:35::i;:::-;7721:208;;:::o;10663:477::-;10762:24;10789:25;10799:5;10806:7;10789:9;:25::i;:::-;10762:52;;10848:17;10828:16;:37;10824:310;;10904:5;10885:16;:24;10881:130;;;10963:7;10972:16;10990:5;10936:60;;;;;;;;;;;;;:::i;:::-;;;;;;;;10881:130;11052:57;11061:5;11068:7;11096:5;11077:16;:24;11103:5;11052:8;:57::i;:::-;10824:310;10752:388;10663:477;;;:::o;5656:300::-;5755:1;5739:18;;:4;:18;;;5735:86;;5807:1;5780:30;;;;;;;;;;;:::i;:::-;;;;;;;;5735:86;5848:1;5834:16;;:2;:16;;;5830:86;;5902:1;5873:32;;;;;;;;;;;:::i;:::-;;;;;;;;5830:86;5925:24;5933:4;5939:2;5943:5;5925:7;:24::i;:::-;5656:300;;;:::o;2065:409:18:-;2143:30;2176:5;:17;2182:10;2176:17;;;;;;;;;;;;;;;2143:50;;2230:4;:19;;;;;;;;;;;;2212:37;;:14;:37;;;;2204:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;2312:92;;;;;;;;2344:4;2312:92;;;;;;2363:14;2312:92;;;;;;2392:1;2312:92;;;;;2292:5;:17;2298:10;2292:17;;;;;;;;;;;;;;;:112;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2440:10;2420:46;;;2451:14;2420:46;;;;;;:::i;:::-;;;;;;;;2132:342;2065:409;:::o;3845:262:13:-;3898:7;3938:11;3921:28;;3929:4;3921:28;;;:63;;;;;3970:14;3953:13;:31;3921:63;3917:184;;;4007:22;4000:29;;;;3917:184;4067:23;:21;:23::i;:::-;4060:30;;3845:262;;:::o;538:107:8:-;598:7;624;:14;632:5;624:14;;;;;;;;;;;;;;;;617:21;;538:107;;;:::o;6021:126:13:-;6067:13;6099:41;6126:13;6099:5;:26;;:41;;;;:::i;:::-;6092:48;;6021:126;:::o;6473:135::-;6522:13;6554:47;6584:16;6554:8;:29;;:47;;;;:::i;:::-;6547:54;;6473:135;:::o;759:395:8:-;819:7;1121;:14;1129:5;1121:14;;;;;;;;;;;;;;;;:16;;;;;;;;;;;;1114:23;;759:395;;;:::o;4917:176:13:-;4994:7;5020:66;5053:20;:18;:20::i;:::-;5075:10;5020:32;:66::i;:::-;5013:73;;4917:176;;;:::o;6598:232:12:-;6683:7;6703:17;6722:18;6744:25;6755:4;6761:1;6764;6767;6744:10;:25::i;:::-;6702:67;;;;6779:18;6791:5;6779:11;:18::i;:::-;6814:9;6807:16;;;;6598:232;;;;;;:::o;4989:229:18:-;5063:16;5082:6;;;;;;;;;;;5063:25;;5108:8;5099:6;;:17;;;;;;;;;;;;;;;;;;5153:1;5127:22;;:27;;;;;;;:::i;:::-;;;;;;;;5201:8;5170:40;;5191:8;5170:40;;;;;;;;;;;;5052:166;4989:229;:::o;1610:447::-;1711:30;1744:5;:17;1750:10;1744:17;;;;;;;;;;;;;;;1711:50;;1803:4;:19;;;;;;;;;;;;1780:42;;:19;:42;;;;1772:82;;;;;;;;;;;;:::i;:::-;;;;;;;;;1885:97;;;;;;;;1917:4;1885:97;;;;;;1936:19;1885:97;;;;;;1970:1;1885:97;;;;;1865:5;:17;1871:10;1865:17;;;;;;;;;;;;;;;:117;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2018:10;1998:51;;;2029:19;1998:51;;;;;;:::i;:::-;;;;;;;;1700:357;1610:447;;:::o;9949:432:2:-;10078:1;10061:19;;:5;:19;;;10057:89;;10132:1;10103:32;;;;;;;;;;;:::i;:::-;;;;;;;;10057:89;10178:1;10159:21;;:7;:21;;;10155:90;;10231:1;10203:31;;;;;;;;;;;:::i;:::-;;;;;;;;10155:90;10284:5;10254:11;:18;10266:5;10254:18;;;;;;;;;;;;;;;:27;10273:7;10254:27;;;;;;;;;;;;;;;:35;;;;10303:9;10299:76;;;10349:7;10333:31;;10342:5;10333:31;;;10358:5;10333:31;;;;;;:::i;:::-;;;;;;;;10299:76;9949:432;;;;:::o;6271:1107::-;6376:1;6360:18;;:4;:18;;;6356:540;;6512:5;6496:12;;:21;;;;;;;:::i;:::-;;;;;;;;6356:540;;;6548:19;6570:9;:15;6580:4;6570:15;;;;;;;;;;;;;;;;6548:37;;6617:5;6603:11;:19;6599:115;;;6674:4;6680:11;6693:5;6649:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;6599:115;6866:5;6852:11;:19;6834:9;:15;6844:4;6834:15;;;;;;;;;;;;;;;:37;;;;6534:362;6356:540;6924:1;6910:16;;:2;:16;;;6906:425;;7089:5;7073:12;;:21;;;;;;;;;;;6906:425;;;7301:5;7284:9;:13;7294:2;7284:13;;;;;;;;;;;;;;;;:22;;;;;;;;;;;6906:425;7361:2;7346:25;;7355:4;7346:25;;;7365:5;7346:25;;;;;;:::i;:::-;;;;;;;;6271:1107;;;:::o;4113:179:13:-;4168:7;2079:95;4226:11;4239:14;4255:13;4278:4;4204:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4194:91;;;;;;4187:98;;4113:179;:::o;3367:268:9:-;3461:13;1371:66;3519:18;;3509:5;3490:47;3486:143;;3560:15;3569:5;3560:8;:15::i;:::-;3553:22;;;;3486:143;3613:5;3606:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3367:268;;;;;:::o;3353:401:14:-;3446:14;3555:4;3549:11;3585:10;3580:3;3573:23;3632:15;3625:4;3620:3;3616:14;3609:39;3684:10;3677:4;3672:3;3668:14;3661:34;3733:4;3728:3;3718:20;3708:30;;3524:224;3353:401;;;;:::o;5009:1456:12:-;5097:7;5106:12;6021:66;6016:1;6008:10;;:79;6004:161;;;6119:1;6123:30;6103:51;;;;;;6004:161;6259:14;6276:24;6286:4;6292:1;6295;6298;6276:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6259:41;;6332:1;6314:20;;:6;:20;;;6310:101;;6366:1;6370:29;6350:50;;;;;;;6310:101;6429:6;6437:20;6421:37;;;;;5009:1456;;;;;;;;:::o;570:511::-;647:20;638:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;634:441;683:7;634:441;743:29;734:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;730:345;;788:34;;;;;;;;;;:::i;:::-;;;;;;;;730:345;852:35;843:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;839:236;;903:41;;;;;;;;;;:::i;:::-;;;;;;;;839:236;974:30;965:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;961:114;;1020:44;;;;;;;;;;:::i;:::-;;;;;;;;961:114;570:511;;:::o;2059:405:9:-;2118:13;2143:11;2157:16;2168:4;2157:10;:16::i;:::-;2143:30;;2261:17;2292:2;2281:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2261:34;;2383:3;2378;2371:16;2423:4;2416;2411:3;2407:14;2400:28;2454:3;2447:10;;;;2059:405;;;:::o;2536:245::-;2597:7;2616:14;2669:4;2660;2633:33;;:40;2616:57;;2696:2;2687:6;:11;2683:69;;;2721:20;;;;;;;;;;;;;;2683:69;2768:6;2761:13;;;2536:245;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:99:20:-;59:6;93:5;87:12;77:22;;7:99;;;:::o;112:169::-;196:11;230:6;225:3;218:19;270:4;265:3;261:14;246:29;;112:169;;;;:::o;287:246::-;368:1;378:113;392:6;389:1;386:13;378:113;;;477:1;472:3;468:11;462:18;458:1;453:3;449:11;442:39;414:2;411:1;407:10;402:15;;378:113;;;525:1;516:6;511:3;507:16;500:27;349:184;287:246;;;:::o;539:102::-;580:6;631:2;627:7;622:2;615:5;611:14;607:28;597:38;;539:102;;;:::o;647:377::-;735:3;763:39;796:5;763:39;:::i;:::-;818:71;882:6;877:3;818:71;:::i;:::-;811:78;;898:65;956:6;951:3;944:4;937:5;933:16;898:65;:::i;:::-;988:29;1010:6;988:29;:::i;:::-;983:3;979:39;972:46;;739:285;647:377;;;;:::o;1030:313::-;1143:4;1181:2;1170:9;1166:18;1158:26;;1230:9;1224:4;1220:20;1216:1;1205:9;1201:17;1194:47;1258:78;1331:4;1322:6;1258:78;:::i;:::-;1250:86;;1030:313;;;;:::o;1349:75::-;1382:6;1415:2;1409:9;1399:19;;1349:75;:::o;1430:117::-;1539:1;1536;1529:12;1676:126;1713:7;1753:42;1746:5;1742:54;1731:65;;1676:126;;;:::o;1808:96::-;1845:7;1874:24;1892:5;1874:24;:::i;:::-;1863:35;;1808:96;;;:::o;1910:122::-;1983:24;2001:5;1983:24;:::i;:::-;1976:5;1973:35;1963:63;;2022:1;2019;2012:12;1963:63;1910:122;:::o;2038:139::-;2084:5;2122:6;2109:20;2100:29;;2138:33;2165:5;2138:33;:::i;:::-;2038:139;;;;:::o;2183:77::-;2220:7;2249:5;2238:16;;2183:77;;;:::o;2266:122::-;2339:24;2357:5;2339:24;:::i;:::-;2332:5;2329:35;2319:63;;2378:1;2375;2368:12;2319:63;2266:122;:::o;2394:139::-;2440:5;2478:6;2465:20;2456:29;;2494:33;2521:5;2494:33;:::i;:::-;2394:139;;;;:::o;2539:474::-;2607:6;2615;2664:2;2652:9;2643:7;2639:23;2635:32;2632:119;;;2670:79;;:::i;:::-;2632:119;2790:1;2815:53;2860:7;2851:6;2840:9;2836:22;2815:53;:::i;:::-;2805:63;;2761:117;2917:2;2943:53;2988:7;2979:6;2968:9;2964:22;2943:53;:::i;:::-;2933:63;;2888:118;2539:474;;;;;:::o;3019:90::-;3053:7;3096:5;3089:13;3082:21;3071:32;;3019:90;;;:::o;3115:109::-;3196:21;3211:5;3196:21;:::i;:::-;3191:3;3184:34;3115:109;;:::o;3230:210::-;3317:4;3355:2;3344:9;3340:18;3332:26;;3368:65;3430:1;3419:9;3415:17;3406:6;3368:65;:::i;:::-;3230:210;;;;:::o;3446:329::-;3505:6;3554:2;3542:9;3533:7;3529:23;3525:32;3522:119;;;3560:79;;:::i;:::-;3522:119;3680:1;3705:53;3750:7;3741:6;3730:9;3726:22;3705:53;:::i;:::-;3695:63;;3651:117;3446:329;;;;:::o;3781:99::-;3852:21;3867:5;3852:21;:::i;:::-;3847:3;3840:34;3781:99;;:::o;3886:93::-;3922:7;3962:10;3955:5;3951:22;3940:33;;3886:93;;;:::o;3985:105::-;4060:23;4077:5;4060:23;:::i;:::-;4055:3;4048:36;3985:105;;:::o;4096:97::-;4132:7;4172:14;4165:5;4161:26;4150:37;;4096:97;;;:::o;4199:105::-;4274:23;4291:5;4274:23;:::i;:::-;4269:3;4262:36;4199:105;;:::o;4390:716::-;4557:4;4552:3;4548:14;4646:4;4639:5;4635:16;4629:23;4665:57;4716:4;4711:3;4707:14;4693:12;4665:57;:::i;:::-;4572:160;4824:4;4817:5;4813:16;4807:23;4843:61;4898:4;4893:3;4889:14;4875:12;4843:61;:::i;:::-;4742:172;5009:4;5002:5;4998:16;4992:23;5028:61;5083:4;5078:3;5074:14;5060:12;5028:61;:::i;:::-;4924:175;4526:580;4390:716;;:::o;5112:362::-;5275:4;5313:2;5302:9;5298:18;5290:26;;5326:141;5464:1;5453:9;5449:17;5440:6;5326:141;:::i;:::-;5112:362;;;;:::o;5480:118::-;5567:24;5585:5;5567:24;:::i;:::-;5562:3;5555:37;5480:118;;:::o;5604:222::-;5697:4;5735:2;5724:9;5720:18;5712:26;;5748:71;5816:1;5805:9;5801:17;5792:6;5748:71;:::i;:::-;5604:222;;;;:::o;5832:117::-;5941:1;5938;5931:12;5955:180;6003:77;6000:1;5993:88;6100:4;6097:1;6090:15;6124:4;6121:1;6114:15;6141:281;6224:27;6246:4;6224:27;:::i;:::-;6216:6;6212:40;6354:6;6342:10;6339:22;6318:18;6306:10;6303:34;6300:62;6297:88;;;6365:18;;:::i;:::-;6297:88;6405:10;6401:2;6394:22;6184:238;6141:281;;:::o;6428:129::-;6462:6;6489:20;;:::i;:::-;6479:30;;6518:33;6546:4;6538:6;6518:33;:::i;:::-;6428:129;;;:::o;6563:249::-;6638:4;6728:18;6720:6;6717:30;6714:56;;;6750:18;;:::i;:::-;6714:56;6800:4;6792:6;6788:17;6780:25;;6563:249;;;:::o;6818:117::-;6927:1;6924;6917:12;6959:643;7053:5;7078:79;7094:62;7149:6;7094:62;:::i;:::-;7078:79;:::i;:::-;7069:88;;7177:5;7230:4;7222:6;7218:17;7210:6;7206:30;7259:3;7251:6;7248:15;7245:122;;;7278:79;;:::i;:::-;7245:122;7393:6;7376:220;7410:6;7405:3;7402:15;7376:220;;;7485:3;7514:37;7547:3;7535:10;7514:37;:::i;:::-;7509:3;7502:50;7581:4;7576:3;7572:14;7565:21;;7452:144;7436:4;7431:3;7427:14;7420:21;;7376:220;;;7380:21;7059:543;;6959:643;;;;;:::o;7626:339::-;7695:5;7744:3;7737:4;7729:6;7725:17;7721:27;7711:122;;7752:79;;:::i;:::-;7711:122;7856:4;7878:81;7955:3;7947:6;7939;7878:81;:::i;:::-;7869:90;;7701:264;7626:339;;;;:::o;7971:376::-;8053:6;8102:3;8090:9;8081:7;8077:23;8073:33;8070:120;;;8109:79;;:::i;:::-;8070:120;8229:1;8254:76;8322:7;8313:6;8302:9;8298:22;8254:76;:::i;:::-;8244:86;;8200:140;7971:376;;;;:::o;8353:619::-;8430:6;8438;8446;8495:2;8483:9;8474:7;8470:23;8466:32;8463:119;;;8501:79;;:::i;:::-;8463:119;8621:1;8646:53;8691:7;8682:6;8671:9;8667:22;8646:53;:::i;:::-;8636:63;;8592:117;8748:2;8774:53;8819:7;8810:6;8799:9;8795:22;8774:53;:::i;:::-;8764:63;;8719:118;8876:2;8902:53;8947:7;8938:6;8927:9;8923:22;8902:53;:::i;:::-;8892:63;;8847:118;8353:619;;;;;:::o;8978:118::-;9065:24;9083:5;9065:24;:::i;:::-;9060:3;9053:37;8978:118;;:::o;9102:222::-;9195:4;9233:2;9222:9;9218:18;9210:26;;9246:71;9314:1;9303:9;9299:17;9290:6;9246:71;:::i;:::-;9102:222;;;;:::o;9330:120::-;9402:23;9419:5;9402:23;:::i;:::-;9395:5;9392:34;9382:62;;9440:1;9437;9430:12;9382:62;9330:120;:::o;9456:137::-;9501:5;9539:6;9526:20;9517:29;;9555:32;9581:5;9555:32;:::i;:::-;9456:137;;;;:::o;9599:327::-;9657:6;9706:2;9694:9;9685:7;9681:23;9677:32;9674:119;;;9712:79;;:::i;:::-;9674:119;9832:1;9857:52;9901:7;9892:6;9881:9;9877:22;9857:52;:::i;:::-;9847:62;;9803:116;9599:327;;;;:::o;9932:86::-;9967:7;10007:4;10000:5;9996:16;9985:27;;9932:86;;;:::o;10024:112::-;10107:22;10123:5;10107:22;:::i;:::-;10102:3;10095:35;10024:112;;:::o;10142:214::-;10231:4;10269:2;10258:9;10254:18;10246:26;;10282:67;10346:1;10335:9;10331:17;10322:6;10282:67;:::i;:::-;10142:214;;;;:::o;10362:77::-;10399:7;10428:5;10417:16;;10362:77;;;:::o;10445:118::-;10532:24;10550:5;10532:24;:::i;:::-;10527:3;10520:37;10445:118;;:::o;10569:222::-;10662:4;10700:2;10689:9;10685:18;10677:26;;10713:71;10781:1;10770:9;10766:17;10757:6;10713:71;:::i;:::-;10569:222;;;;:::o;10797:149::-;10833:7;10873:66;10866:5;10862:78;10851:89;;10797:149;;;:::o;10952:115::-;11037:23;11054:5;11037:23;:::i;:::-;11032:3;11025:36;10952:115;;:::o;11073:114::-;11140:6;11174:5;11168:12;11158:22;;11073:114;;;:::o;11193:184::-;11292:11;11326:6;11321:3;11314:19;11366:4;11361:3;11357:14;11342:29;;11193:184;;;;:::o;11383:132::-;11450:4;11473:3;11465:11;;11503:4;11498:3;11494:14;11486:22;;11383:132;;;:::o;11521:108::-;11598:24;11616:5;11598:24;:::i;:::-;11593:3;11586:37;11521:108;;:::o;11635:179::-;11704:10;11725:46;11767:3;11759:6;11725:46;:::i;:::-;11803:4;11798:3;11794:14;11780:28;;11635:179;;;;:::o;11820:113::-;11890:4;11922;11917:3;11913:14;11905:22;;11820:113;;;:::o;11969:732::-;12088:3;12117:54;12165:5;12117:54;:::i;:::-;12187:86;12266:6;12261:3;12187:86;:::i;:::-;12180:93;;12297:56;12347:5;12297:56;:::i;:::-;12376:7;12407:1;12392:284;12417:6;12414:1;12411:13;12392:284;;;12493:6;12487:13;12520:63;12579:3;12564:13;12520:63;:::i;:::-;12513:70;;12606:60;12659:6;12606:60;:::i;:::-;12596:70;;12452:224;12439:1;12436;12432:9;12427:14;;12392:284;;;12396:14;12692:3;12685:10;;12093:608;;;11969:732;;;;:::o;12707:1215::-;13056:4;13094:3;13083:9;13079:19;13071:27;;13108:69;13174:1;13163:9;13159:17;13150:6;13108:69;:::i;:::-;13224:9;13218:4;13214:20;13209:2;13198:9;13194:18;13187:48;13252:78;13325:4;13316:6;13252:78;:::i;:::-;13244:86;;13377:9;13371:4;13367:20;13362:2;13351:9;13347:18;13340:48;13405:78;13478:4;13469:6;13405:78;:::i;:::-;13397:86;;13493:72;13561:2;13550:9;13546:18;13537:6;13493:72;:::i;:::-;13575:73;13643:3;13632:9;13628:19;13619:6;13575:73;:::i;:::-;13658;13726:3;13715:9;13711:19;13702:6;13658:73;:::i;:::-;13779:9;13773:4;13769:20;13763:3;13752:9;13748:19;13741:49;13807:108;13910:4;13901:6;13807:108;:::i;:::-;13799:116;;12707:1215;;;;;;;;;;:::o;13928:115::-;14013:23;14030:5;14013:23;:::i;:::-;14008:3;14001:36;13928:115;;:::o;14049:::-;14134:23;14151:5;14134:23;:::i;:::-;14129:3;14122:36;14049:115;;:::o;14170:422::-;14309:4;14347:2;14336:9;14332:18;14324:26;;14360:65;14422:1;14411:9;14407:17;14398:6;14360:65;:::i;:::-;14435:70;14501:2;14490:9;14486:18;14477:6;14435:70;:::i;:::-;14515;14581:2;14570:9;14566:18;14557:6;14515:70;:::i;:::-;14170:422;;;;;;:::o;14598:118::-;14669:22;14685:5;14669:22;:::i;:::-;14662:5;14659:33;14649:61;;14706:1;14703;14696:12;14649:61;14598:118;:::o;14722:135::-;14766:5;14804:6;14791:20;14782:29;;14820:31;14845:5;14820:31;:::i;:::-;14722:135;;;;:::o;14863:122::-;14936:24;14954:5;14936:24;:::i;:::-;14929:5;14926:35;14916:63;;14975:1;14972;14965:12;14916:63;14863:122;:::o;14991:139::-;15037:5;15075:6;15062:20;15053:29;;15091:33;15118:5;15091:33;:::i;:::-;14991:139;;;;:::o;15136:1199::-;15247:6;15255;15263;15271;15279;15287;15295;15344:3;15332:9;15323:7;15319:23;15315:33;15312:120;;;15351:79;;:::i;:::-;15312:120;15471:1;15496:53;15541:7;15532:6;15521:9;15517:22;15496:53;:::i;:::-;15486:63;;15442:117;15598:2;15624:53;15669:7;15660:6;15649:9;15645:22;15624:53;:::i;:::-;15614:63;;15569:118;15726:2;15752:53;15797:7;15788:6;15777:9;15773:22;15752:53;:::i;:::-;15742:63;;15697:118;15854:2;15880:53;15925:7;15916:6;15905:9;15901:22;15880:53;:::i;:::-;15870:63;;15825:118;15982:3;16009:51;16052:7;16043:6;16032:9;16028:22;16009:51;:::i;:::-;15999:61;;15953:117;16109:3;16136:53;16181:7;16172:6;16161:9;16157:22;16136:53;:::i;:::-;16126:63;;16080:119;16238:3;16265:53;16310:7;16301:6;16290:9;16286:22;16265:53;:::i;:::-;16255:63;;16209:119;15136:1199;;;;;;;;;;:::o;16341:474::-;16409:6;16417;16466:2;16454:9;16445:7;16441:23;16437:32;16434:119;;;16472:79;;:::i;:::-;16434:119;16592:1;16617:53;16662:7;16653:6;16642:9;16638:22;16617:53;:::i;:::-;16607:63;;16563:117;16719:2;16745:53;16790:7;16781:6;16770:9;16766:22;16745:53;:::i;:::-;16735:63;;16690:118;16341:474;;;;;:::o;16821:180::-;16869:77;16866:1;16859:88;16966:4;16963:1;16956:15;16990:4;16987:1;16980:15;17007:320;17051:6;17088:1;17082:4;17078:12;17068:22;;17135:1;17129:4;17125:12;17156:18;17146:81;;17212:4;17204:6;17200:17;17190:27;;17146:81;17274:2;17266:6;17263:14;17243:18;17240:38;17237:84;;17293:18;;:::i;:::-;17237:84;17058:269;17007:320;;;:::o;17333:180::-;17381:77;17378:1;17371:88;17478:4;17475:1;17468:15;17502:4;17499:1;17492:15;17519:180;17567:77;17564:1;17557:88;17664:4;17661:1;17654:15;17688:4;17685:1;17678:15;17705:410;17745:7;17768:20;17786:1;17768:20;:::i;:::-;17763:25;;17802:20;17820:1;17802:20;:::i;:::-;17797:25;;17857:1;17854;17850:9;17879:30;17897:11;17879:30;:::i;:::-;17868:41;;18058:1;18049:7;18045:15;18042:1;18039:22;18019:1;18012:9;17992:83;17969:139;;18088:18;;:::i;:::-;17969:139;17753:362;17705:410;;;;:::o;18121:180::-;18169:77;18166:1;18159:88;18266:4;18263:1;18256:15;18290:4;18287:1;18280:15;18307:185;18347:1;18364:20;18382:1;18364:20;:::i;:::-;18359:25;;18398:20;18416:1;18398:20;:::i;:::-;18393:25;;18437:1;18427:35;;18442:18;;:::i;:::-;18427:35;18484:1;18481;18477:9;18472:14;;18307:185;;;;:::o;18498:170::-;18638:22;18634:1;18626:6;18622:14;18615:46;18498:170;:::o;18674:366::-;18816:3;18837:67;18901:2;18896:3;18837:67;:::i;:::-;18830:74;;18913:93;19002:3;18913:93;:::i;:::-;19031:2;19026:3;19022:12;19015:19;;18674:366;;;:::o;19046:419::-;19212:4;19250:2;19239:9;19235:18;19227:26;;19299:9;19293:4;19289:20;19285:1;19274:9;19270:17;19263:47;19327:131;19453:4;19327:131;:::i;:::-;19319:139;;19046:419;;;:::o;19471:160::-;19611:12;19607:1;19599:6;19595:14;19588:36;19471:160;:::o;19637:366::-;19779:3;19800:67;19864:2;19859:3;19800:67;:::i;:::-;19793:74;;19876:93;19965:3;19876:93;:::i;:::-;19994:2;19989:3;19985:12;19978:19;;19637:366;;;:::o;20009:419::-;20175:4;20213:2;20202:9;20198:18;20190:26;;20262:9;20256:4;20252:20;20248:1;20237:9;20233:17;20226:47;20290:131;20416:4;20290:131;:::i;:::-;20282:139;;20009:419;;;:::o;20434:166::-;20574:18;20570:1;20562:6;20558:14;20551:42;20434:166;:::o;20606:366::-;20748:3;20769:67;20833:2;20828:3;20769:67;:::i;:::-;20762:74;;20845:93;20934:3;20845:93;:::i;:::-;20963:2;20958:3;20954:12;20947:19;;20606:366;;;:::o;20978:419::-;21144:4;21182:2;21171:9;21167:18;21159:26;;21231:9;21225:4;21221:20;21217:1;21206:9;21202:17;21195:47;21259:131;21385:4;21259:131;:::i;:::-;21251:139;;20978:419;;;:::o;21403:201::-;21442:3;21461:19;21478:1;21461:19;:::i;:::-;21456:24;;21494:19;21511:1;21494:19;:::i;:::-;21489:24;;21536:1;21533;21529:9;21522:16;;21559:14;21554:3;21551:23;21548:49;;;21577:18;;:::i;:::-;21548:49;21403:201;;;;:::o;21610:60::-;21638:3;21659:5;21652:12;;21610:60;;;:::o;21676:140::-;21725:9;21758:52;21776:33;21785:23;21802:5;21785:23;:::i;:::-;21776:33;:::i;:::-;21758:52;:::i;:::-;21745:65;;21676:140;;;:::o;21822:129::-;21908:36;21938:5;21908:36;:::i;:::-;21903:3;21896:49;21822:129;;:::o;21957:220::-;22049:4;22087:2;22076:9;22072:18;22064:26;;22100:70;22167:1;22156:9;22152:17;22143:6;22100:70;:::i;:::-;21957:220;;;;:::o;22183:775::-;22416:4;22454:3;22443:9;22439:19;22431:27;;22468:71;22536:1;22525:9;22521:17;22512:6;22468:71;:::i;:::-;22549:72;22617:2;22606:9;22602:18;22593:6;22549:72;:::i;:::-;22631;22699:2;22688:9;22684:18;22675:6;22631:72;:::i;:::-;22713;22781:2;22770:9;22766:18;22757:6;22713:72;:::i;:::-;22795:73;22863:3;22852:9;22848:19;22839:6;22795:73;:::i;:::-;22878;22946:3;22935:9;22931:19;22922:6;22878:73;:::i;:::-;22183:775;;;;;;;;;:::o;22964:332::-;23085:4;23123:2;23112:9;23108:18;23100:26;;23136:71;23204:1;23193:9;23189:17;23180:6;23136:71;:::i;:::-;23217:72;23285:2;23274:9;23270:18;23261:6;23217:72;:::i;:::-;22964:332;;;;;:::o;23302:225::-;23442:34;23438:1;23430:6;23426:14;23419:58;23511:8;23506:2;23498:6;23494:15;23487:33;23302:225;:::o;23533:366::-;23675:3;23696:67;23760:2;23755:3;23696:67;:::i;:::-;23689:74;;23772:93;23861:3;23772:93;:::i;:::-;23890:2;23885:3;23881:12;23874:19;;23533:366;;;:::o;23905:419::-;24071:4;24109:2;24098:9;24094:18;24086:26;;24158:9;24152:4;24148:20;24144:1;24133:9;24129:17;24122:47;24186:131;24312:4;24186:131;:::i;:::-;24178:139;;23905:419;;;:::o;24330:178::-;24470:30;24466:1;24458:6;24454:14;24447:54;24330:178;:::o;24514:366::-;24656:3;24677:67;24741:2;24736:3;24677:67;:::i;:::-;24670:74;;24753:93;24842:3;24753:93;:::i;:::-;24871:2;24866:3;24862:12;24855:19;;24514:366;;;:::o;24886:419::-;25052:4;25090:2;25079:9;25075:18;25067:26;;25139:9;25133:4;25129:20;25125:1;25114:9;25110:17;25103:47;25167:131;25293:4;25167:131;:::i;:::-;25159:139;;24886:419;;;:::o;25311:175::-;25451:27;25447:1;25439:6;25435:14;25428:51;25311:175;:::o;25492:366::-;25634:3;25655:67;25719:2;25714:3;25655:67;:::i;:::-;25648:74;;25731:93;25820:3;25731:93;:::i;:::-;25849:2;25844:3;25840:12;25833:19;;25492:366;;;:::o;25864:419::-;26030:4;26068:2;26057:9;26053:18;26045:26;;26117:9;26111:4;26107:20;26103:1;26092:9;26088:17;26081:47;26145:131;26271:4;26145:131;:::i;:::-;26137:139;;25864:419;;;:::o;26289:182::-;26429:34;26425:1;26417:6;26413:14;26406:58;26289:182;:::o;26477:366::-;26619:3;26640:67;26704:2;26699:3;26640:67;:::i;:::-;26633:74;;26716:93;26805:3;26716:93;:::i;:::-;26834:2;26829:3;26825:12;26818:19;;26477:366;;;:::o;26849:419::-;27015:4;27053:2;27042:9;27038:18;27030:26;;27102:9;27096:4;27092:20;27088:1;27077:9;27073:17;27066:47;27130:131;27256:4;27130:131;:::i;:::-;27122:139;;26849:419;;;:::o;27274:442::-;27423:4;27461:2;27450:9;27446:18;27438:26;;27474:71;27542:1;27531:9;27527:17;27518:6;27474:71;:::i;:::-;27555:72;27623:2;27612:9;27608:18;27599:6;27555:72;:::i;:::-;27637;27705:2;27694:9;27690:18;27681:6;27637:72;:::i;:::-;27274:442;;;;;;:::o;27722:177::-;27862:29;27858:1;27850:6;27846:14;27839:53;27722:177;:::o;27905:366::-;28047:3;28068:67;28132:2;28127:3;28068:67;:::i;:::-;28061:74;;28144:93;28233:3;28144:93;:::i;:::-;28262:2;28257:3;28253:12;28246:19;;27905:366;;;:::o;28277:419::-;28443:4;28481:2;28470:9;28466:18;28458:26;;28530:9;28524:4;28520:20;28516:1;28505:9;28501:17;28494:47;28558:131;28684:4;28558:131;:::i;:::-;28550:139;;28277:419;;;:::o;28702:140::-;28751:9;28784:52;28802:33;28811:23;28828:5;28811:23;:::i;:::-;28802:33;:::i;:::-;28784:52;:::i;:::-;28771:65;;28702:140;;;:::o;28848:129::-;28934:36;28964:5;28934:36;:::i;:::-;28929:3;28922:49;28848:129;;:::o;28983:220::-;29075:4;29113:2;29102:9;29098:18;29090:26;;29126:70;29193:1;29182:9;29178:17;29169:6;29126:70;:::i;:::-;28983:220;;;;:::o;29209:191::-;29249:3;29268:20;29286:1;29268:20;:::i;:::-;29263:25;;29302:20;29320:1;29302:20;:::i;:::-;29297:25;;29345:1;29342;29338:9;29331:16;;29366:3;29363:1;29360:10;29357:36;;;29373:18;;:::i;:::-;29357:36;29209:191;;;;:::o;29406:664::-;29611:4;29649:3;29638:9;29634:19;29626:27;;29663:71;29731:1;29720:9;29716:17;29707:6;29663:71;:::i;:::-;29744:72;29812:2;29801:9;29797:18;29788:6;29744:72;:::i;:::-;29826;29894:2;29883:9;29879:18;29870:6;29826:72;:::i;:::-;29908;29976:2;29965:9;29961:18;29952:6;29908:72;:::i;:::-;29990:73;30058:3;30047:9;30043:19;30034:6;29990:73;:::i;:::-;29406:664;;;;;;;;:::o;30076:545::-;30249:4;30287:3;30276:9;30272:19;30264:27;;30301:71;30369:1;30358:9;30354:17;30345:6;30301:71;:::i;:::-;30382:68;30446:2;30435:9;30431:18;30422:6;30382:68;:::i;:::-;30460:72;30528:2;30517:9;30513:18;30504:6;30460:72;:::i;:::-;30542;30610:2;30599:9;30595:18;30586:6;30542:72;:::i;:::-;30076:545;;;;;;;:::o;30627:180::-;30675:77;30672:1;30665:88;30772:4;30769:1;30762:15;30796:4;30793:1;30786:15;30813:174;30953:26;30949:1;30941:6;30937:14;30930:50;30813:174;:::o;30993:366::-;31135:3;31156:67;31220:2;31215:3;31156:67;:::i;:::-;31149:74;;31232:93;31321:3;31232:93;:::i;:::-;31350:2;31345:3;31341:12;31334:19;;30993:366;;;:::o;31365:419::-;31531:4;31569:2;31558:9;31554:18;31546:26;;31618:9;31612:4;31608:20;31604:1;31593:9;31589:17;31582:47;31646:131;31772:4;31646:131;:::i;:::-;31638:139;;31365:419;;;:::o;31790:181::-;31930:33;31926:1;31918:6;31914:14;31907:57;31790:181;:::o;31977:366::-;32119:3;32140:67;32204:2;32199:3;32140:67;:::i;:::-;32133:74;;32216:93;32305:3;32216:93;:::i;:::-;32334:2;32329:3;32325:12;32318:19;;31977:366;;;:::o;32349:419::-;32515:4;32553:2;32542:9;32538:18;32530:26;;32602:9;32596:4;32592:20;32588:1;32577:9;32573:17;32566:47;32630:131;32756:4;32630:131;:::i;:::-;32622:139;;32349:419;;;:::o;32774:221::-;32914:34;32910:1;32902:6;32898:14;32891:58;32983:4;32978:2;32970:6;32966:15;32959:29;32774:221;:::o;33001:366::-;33143:3;33164:67;33228:2;33223:3;33164:67;:::i;:::-;33157:74;;33240:93;33329:3;33240:93;:::i;:::-;33358:2;33353:3;33349:12;33342:19;;33001:366;;;:::o;33373:419::-;33539:4;33577:2;33566:9;33562:18;33554:26;;33626:9;33620:4;33616:20;33612:1;33601:9;33597:17;33590:47;33654:131;33780:4;33654:131;:::i;:::-;33646:139;;33373:419;;;:::o

Swarm Source

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