ETH Price: $2,977.06 (-1.43%)
 

Overview

Max Total Supply

0 GRAMS

Holders

0

Transfers

-
0

Market

Onchain Market Cap

-

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
StableCoin

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2024-04-22
*/

// SPDX-License-Identifier: MIT
// File: StableCoin_flat.sol


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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
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: @openzeppelin/contracts/utils/introspection/IERC165.sol


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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


// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

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


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

pragma solidity ^0.8.0;

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

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

// File: contracts/Ownable.sol


pragma solidity ^0.8.0;


contract Ownable is Context {
    address private _owner;
    address private _proposedOwner;

    event ProposeOwner(address indexed proposedOwner);
    event ClaimOwnership(address newOwner);

    constructor() {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit ClaimOwnership(msgSender);
    }

    function owner() public view returns (address) {
        return _owner;
    }

    function proposedOwner() public view returns (address) {
        return _proposedOwner;
    }

    modifier onlyOwner() {
        require(
            _owner == _msgSender(),
            "Only the owner can call this function."
        );
        _;
    }

    modifier onlyProposedOwner() {
        require(
            _msgSender() == _proposedOwner,
            "Only the proposed owner can call this function."
        );
        _;
    }

    function disregardProposedOwner() private onlyOwner {
        _proposedOwner = address(0);
    }

    function proposeOwner(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Cannot propose 0x0 as new owner.");
        _proposedOwner = newOwner;
        emit ProposeOwner(_proposedOwner);
    }

    function claimOwnership() public virtual onlyProposedOwner {
        _owner = _proposedOwner;
        _proposedOwner = address(0);
        emit ClaimOwnership(_owner);
    }

    uint256[49] private __gap;
}
// File: contracts/ExternallyTransferable.sol


pragma solidity ^0.8.0;



abstract contract ExternallyTransferable is Context {
    using SafeMath for uint256;

    // address => string (network URI) => bytes (external address) => amount
    mapping(address => mapping(string => mapping(bytes => uint256)))
        private _externalAllowances;

    function externalAllowanceOf(
        address owner,
        string memory networkURI,
        bytes memory externalAddress
    ) public view returns (uint256) {
        return _externalAllowances[owner][networkURI][externalAddress];
    }

    // User calls to allocate external transfer
    function approveExternalTransfer(
        string memory networkURI,
        bytes memory externalAddress,
        uint256 amount
    ) public virtual {
        _approveExternalAllowance(_msgSender(), networkURI, externalAddress, amount);
    }

    // Bridge calls after externalTransfer
    function _approveExternalAllowance(
        address from,
        string memory networkURI,
        bytes memory to,
        uint256 amount
    ) internal virtual {
        require(_msgSender() != address(0), "Approve from the zero address");
        require(from != address(0), "Approve for the zero address");
        _externalAllowances[from][networkURI][to] = amount;
    }

    // Bridge calls to burn coins on this network (sending external transfer)
    function externalTransfer(
        address from,
        string memory networkURI,
        bytes memory to, // external address
        uint256 amount
    ) public virtual {}

    // Bridge calls to mint coins on this network (receiving external transfer)
    function externalTransferFrom(
        bytes memory from, // external address
        string memory networkURI,
        address to,
        uint256 amount
    ) public virtual {}
}
// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


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

pragma solidity ^0.8.0;




/**
 * @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}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * 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.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * 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 override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override 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 value {ERC20} uses, unless this function is
     * 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 override returns (uint8) {
        return 18;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override 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 `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

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

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` 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 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        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 `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowances[owner][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowances[owner][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * 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.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

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

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` 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.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

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


// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;





/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

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


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

pragma solidity ^0.8.0;


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

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

    bool private _paused;

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

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

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

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

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

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

// File: contracts/StableCoin.sol


pragma solidity ^0.8.0;

contract StableCoin is
    Context, // provides _msgSender(), _msgData()
    Pausable, // provides _pause(), _unpause()
    Ownable, // Ownable, Claimable
    AccessControl, // RBAC for KYC, Frozen
    ERC20, // ERC20 Functions (transfer, balance, allowance, mint, burn)
    ExternallyTransferable // Supports External Transfers
{
    using SafeMath for uint256;
    //using SafeERC20 for IERC20;

    // Defined Roles
    bytes32 private constant KYC_PASSED = keccak256("KYC_PASSED");
    bytes32 private constant FROZEN = keccak256("FROZEN");

    // Special People
    address private _supplyManager;
    address private _complianceManager;
    address private _enforcementManager;

    // Events Emitted
    event Constructed(
        string tokenName,
        string tokenSymbol,
        uint256 totalSupply
    );

    // Privileged Roles
    event ChangeSupplyManager(address newSupplyManager);
    event ChangeComplianceManager(address newComplianceManager);
    event ChangeEnforcementManager(address newEnforcementManager);

    // ERC20+
    event Wipe(address account, uint256 amount);
    event Mint(address account, uint256 amount);
    event Burn(address account, uint256 amount);
    //event Transfer(address sender, address recipient, uint256 amount);
    event Approve(address sender, address spender, uint256 amount);
    event IncreaseAllowance(address sender, address spender, uint256 amount);
    event DecreaseAllowance(address sender, address spender, uint256 amount);

    // KYC
    event Freeze(address account); // Freeze: Freeze this account
    event Unfreeze(address account);
    event SetKycPassed(address account);
    event UnsetKycPassed(address account);

    // Halt
    event Pause(address sender); // Pause: Pause entire contract
    event Unpause(address sender);

    // "External Transfer"
    // Signify to the coin bridge to perform external transfer
    event ApproveExternalTransfer(address from,string networkURI,bytes to,uint256 amount);
    event ExternalTransfer(address from,string networkURI,bytes to,uint256 amount);
    event ExternalTransferFrom(bytes from,string networkURI,address to,uint256 amount);

    constructor() ERC20("Gram Silver", "GRAMS") {
        _supplyManager = _msgSender();
        _complianceManager = _msgSender();
        _enforcementManager = _msgSender();

        // Owner has Admin Privileges on all roles
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); // sudo role

        // Give CM ability to grant/revoke roles (but not admin of this role)
        grantRole(DEFAULT_ADMIN_ROLE, _msgSender());

        // KYC accounts
        grantRole(KYC_PASSED, _msgSender());
        grantRole(KYC_PASSED, _msgSender());
        grantRole(KYC_PASSED, _msgSender());
        grantRole(KYC_PASSED, _msgSender());

        // Give supply manager all tokens
        mint(0); // Emits Mint

        
        // Did it
        emit Constructed(
            name(),
            symbol(),
            0
        );
    }

    /*
     * RBAC
     */

    function supplyManager() public view returns (address) {
        return _supplyManager;
    }

    modifier onlySupplyManager() {
        require(
            _msgSender() == supplyManager() || _msgSender() == owner(),
            "Only the supply manager can call this function."
        );
        _;
    }

    function changeSupplyManager(address newSupplyManager) public onlyOwner {
        require(
            newSupplyManager != address(0),
            "Cannot change supply manager to 0x0."
        );
        revokeRole(KYC_PASSED, _supplyManager);
        _supplyManager = newSupplyManager;
        grantRole(KYC_PASSED, _supplyManager);
        revokeRole(FROZEN, _supplyManager);
        emit ChangeSupplyManager(newSupplyManager);
    }

    function complianceManager() public view returns (address) {
        return _complianceManager;
    }

    modifier onlyComplianceManager() {
        require(
            _msgSender() == complianceManager() || _msgSender() == owner(),
            "Only the Compliance Manager can call this function."
        );
        _;
    }

    function changeComplianceManager(address newComplianceManager)
        public
        onlyOwner
    {
        require(
            newComplianceManager != address(0),
            "Cannot change compliance manager to 0x0."
        );
        revokeRole(KYC_PASSED, _complianceManager);
        _complianceManager = newComplianceManager;
        grantRole(KYC_PASSED, _complianceManager);
        revokeRole(FROZEN, _complianceManager);
        emit ChangeComplianceManager(newComplianceManager);
    }

    function enforcementManager() public view returns (address) {
        return _enforcementManager;
    }

    modifier onlyEnforcementManager() {
        require(
            _msgSender() == enforcementManager() || _msgSender() == owner(),
            "Only the Enforcement Manager can call this function."
        );
        _;
    }

    function changeEnforcementManager(address newEnforcementManager)
        public
        onlyOwner
    {
        require(
            newEnforcementManager != address(0),
            "Cannot change enforcement manager to 0x0"
        );
        revokeRole(KYC_PASSED, _enforcementManager);
        _enforcementManager = newEnforcementManager;
        grantRole(KYC_PASSED, _enforcementManager);
        revokeRole(FROZEN, _enforcementManager);
        emit ChangeEnforcementManager(newEnforcementManager);
    }

    function isPrivilegedRole(address account) public view returns (bool) {
        return
            account == supplyManager() ||
            account == complianceManager() ||
            account == enforcementManager() ||
            account == owner();
    }

    modifier requiresKYC() {
        require(
            hasRole(KYC_PASSED, _msgSender()),
            "Calling this function requires KYC approval."
        );
        _;
    }

    function isKycPassed(address account) public view returns (bool) {
        return hasRole(KYC_PASSED, account);
    }

    // KYC: only CM
    function setKycPassed(address account) public onlyComplianceManager {
        grantRole(KYC_PASSED, account);
        emit SetKycPassed(account);
    }

    // Un-KYC: only CM, only non-privileged accounts
    function unsetKycPassed(address account) public onlyComplianceManager {
        require(
            !isPrivilegedRole(account),
            "Cannot unset KYC for administrator account."
        );
        require(account != address(0), "Cannot unset KYC for address 0x0.");
        revokeRole(KYC_PASSED, account);
        emit UnsetKycPassed(account);
    }

    modifier requiresNotFrozen() {
        require(
            !hasRole(FROZEN, _msgSender()),
            "Your account has been frozen, cannot call function."
        );
        _;
    }

    function isFrozen(address account) public view returns (bool) {
        return hasRole(FROZEN, account);
    }

    // Freeze an account: only CM, only non-privileged accounts
    function freeze(address account) public onlyComplianceManager {
        require(
            !isPrivilegedRole(account),
            "Cannot freeze administrator account."
        );
        require(account != address(0), "Cannot freeze address 0x0.");
        grantRole(FROZEN, account);
        emit Freeze(account);
    }

    // Unfreeze an account: only CM
    function unfreeze(address account) public onlyComplianceManager {
        revokeRole(FROZEN, account);
        emit Unfreeze(account);
    }

    // Check Transfer Allowed (user facing)
    function checkTransferAllowed(address account) public view returns (bool) {
        return isKycPassed(account) && !isFrozen(account);
    }

    // Pause: Only CM
    function pause() public onlyComplianceManager {
        _pause();
        emit Pause(_msgSender());
    }

    // Unpause: Only CM
    function unpause() public onlyComplianceManager {
        _unpause();
        emit Unpause(_msgSender());
    }

    // Claim Ownership
    function claimOwnership() public override(Ownable) onlyProposedOwner {
        address prevOwner = owner();
        super.claimOwnership(); // emits ClaimOwnership
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        grantRole(KYC_PASSED, _msgSender());
        revokeRole(FROZEN, _msgSender());
        revokeRole(KYC_PASSED, prevOwner);
    }

    // Wipe
    function wipe(address account, uint256 amount) public onlyEnforcementManager {
        uint256 balance = balanceOf(account);
        require(
            amount <= balance,
            "Amount cannot be greater than balance"
        );
        super._transfer(account, _supplyManager, amount);
        _burn(_supplyManager, amount);
        emit Wipe(account, amount);
    }

    /*
     * Transfers
     */

    // Mint
    function mint(uint256 amount) public onlySupplyManager {
        _mint(supplyManager(), amount * 10 ** decimals());
        emit Mint(_msgSender(), amount );
    }

    // Burn
    function burn(uint256 amount) public onlySupplyManager {
        _burn(_supplyManager, amount * 10 ** decimals());
        emit Burn(_msgSender(), amount);
    }

    // Check Transfer Allowed (internal)
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal override(ERC20) requiresNotFrozen whenNotPaused {
        if (from == supplyManager() && to == address(0)) {
            // allowed (burn)
            super._beforeTokenTransfer(from, to, amount);
            return;
        }

        if (to == supplyManager() && from == address(0)) {
            // allowed (mint)
            super._beforeTokenTransfer(from, to, amount);
            return;
        }

        if (
            to == supplyManager() &&
            hasRole(FROZEN, from) &&
            amount == balanceOf(from)
        ) {
            // allowed (wipe account)
            super._beforeTokenTransfer(from, to, amount);
            return;
        }

        // All other transfers
        //require(isKycPassed(from), "Sender account requires KYC to continue.");
        //require(isKycPassed(to), "Receiver account requires KYC to continue.");
        require(!isFrozen(from), "Sender account is frozen.");
        require(!isFrozen(to), "Receiver account is frozen.");
        super._beforeTokenTransfer(from, to, amount); // callbacks from above (if any)
    }

    function transfer(address to, uint256 amount) public override(ERC20) returns (bool) {
        super._transfer(_msgSender(), to, amount);
        emit Transfer(_msgSender(), to, amount);
        return  true;
    }

    /*
     * External Transfers
     */

    // approve an allowance for transfer to an external network
    function approveExternalTransfer(
        string memory networkURI,
        bytes memory externalAddress,
        uint256 amount
    )
        public
        override(ExternallyTransferable)
        requiresKYC
        requiresNotFrozen
        whenNotPaused
    {
        require(
            amount <= balanceOf(_msgSender()),
            "Cannot approve more than balance."
        );
        super.approveExternalTransfer(networkURI, externalAddress, amount);
        emit ApproveExternalTransfer(
            _msgSender(),
            networkURI,
            externalAddress,
            amount
        );
    }

    function externalTransfer(
        address from,
        string memory networkURI,
        bytes memory to,
        uint256 amount
    ) public override(ExternallyTransferable) onlySupplyManager whenNotPaused {
        require(isKycPassed(from), "Spender account requires KYC to continue.");
        require(!isFrozen(from), "Spender account is frozen.");
        uint256 exAllowance = externalAllowanceOf(from, networkURI, to);
        require(amount <= exAllowance, "Amount greater than allowance.");
        super._transfer(from, _supplyManager, amount);
        _burn(_supplyManager, amount);
        _approveExternalAllowance(
            from,
            networkURI,
            to,
            exAllowance.sub(amount)
        );
        emit ExternalTransfer(from, networkURI, to, amount);
    }

    function externalTransferFrom(
        bytes memory from,
        string memory networkURI,
        address to,
        uint256 amount
    ) public override(ExternallyTransferable) onlySupplyManager whenNotPaused {
        require(isKycPassed(to), "Recipient account requires KYC to continue.");
        require(!isFrozen(to), "Recipient account is frozen.");
        _mint(_supplyManager, amount);
        super._transfer(_supplyManager, to, amount);
        emit ExternalTransferFrom(from, networkURI, to, amount);
    }

    /*
     * Allowances
     */

    // Check Allowance Allowed (internal)
    function _beforeTokenAllowance(
        address sender,
        address spender,
        uint256 amount
    ) internal requiresKYC requiresNotFrozen whenNotPaused view {
        require(isKycPassed(spender), "Spender account requires KYC to continue.");
        require(isKycPassed(sender), "Sender account requires KYC to continue.");
        require(!isFrozen(spender), "Spender account is frozen.");
        require(!isFrozen(sender), "Sender account is frozen.");
        require(amount >= 0, "Allowance must be greater than 0.");
    }

    // Transfer From (allowance --> user)
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public override requiresKYC requiresNotFrozen returns (bool){
        bool returnValue = super.transferFrom(from, to, amount);
        emit Transfer(from, to, amount);
        emit Approve(from, _msgSender(), allowance(from, _msgSender()));
        return returnValue;
    }

    // Approve Allowance
    function approveAllowance(address spender, uint256 amount)
        public
        requiresKYC
        requiresNotFrozen
    {
        _beforeTokenAllowance(_msgSender(), spender, amount);
        super._approve(_msgSender(), spender, amount);
        emit Approve(_msgSender(), spender, amount);
    }

    // Increase Allowance
    function increaseAllowance(address spender, uint256 amount)
        public
        override(ERC20)
        requiresKYC
        requiresNotFrozen
        returns (bool)
    {
        uint256 newAllowance = allowance(_msgSender(), spender).add(amount);
        _approve(_msgSender(), spender, newAllowance);
        emit IncreaseAllowance(_msgSender(), spender, newAllowance);
        return true;
    }

    // Decrease Allowance
    function decreaseAllowance(address spender, uint256 amount)
        public
        override(ERC20)
        requiresKYC
        requiresNotFrozen
        returns (bool)
    {
        uint256 newAllowance = allowance(_msgSender(), spender).sub(
            amount,
            "Amount greater than allowance."
        );
        _approve(_msgSender(), spender, newAllowance);
        emit DecreaseAllowance(_msgSender(), spender, newAllowance);
        return true;
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approve","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"string","name":"networkURI","type":"string"},{"indexed":false,"internalType":"bytes","name":"to","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ApproveExternalTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newComplianceManager","type":"address"}],"name":"ChangeComplianceManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newEnforcementManager","type":"address"}],"name":"ChangeEnforcementManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newSupplyManager","type":"address"}],"name":"ChangeSupplyManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"ClaimOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"tokenName","type":"string"},{"indexed":false,"internalType":"string","name":"tokenSymbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"Constructed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DecreaseAllowance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"string","name":"networkURI","type":"string"},{"indexed":false,"internalType":"bytes","name":"to","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExternalTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"from","type":"bytes"},{"indexed":false,"internalType":"string","name":"networkURI","type":"string"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExternalTransferFrom","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Freeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"IncreaseAllowance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposedOwner","type":"address"}],"name":"ProposeOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"SetKycPassed","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Unfreeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"UnsetKycPassed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Wipe","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approveAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"networkURI","type":"string"},{"internalType":"bytes","name":"externalAddress","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approveExternalTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newComplianceManager","type":"address"}],"name":"changeComplianceManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newEnforcementManager","type":"address"}],"name":"changeEnforcementManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newSupplyManager","type":"address"}],"name":"changeSupplyManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"checkTransferAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"complianceManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enforcementManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"networkURI","type":"string"},{"internalType":"bytes","name":"externalAddress","type":"bytes"}],"name":"externalAllowanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"string","name":"networkURI","type":"string"},{"internalType":"bytes","name":"to","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"externalTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"from","type":"bytes"},{"internalType":"string","name":"networkURI","type":"string"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"externalTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isKycPassed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isPrivilegedRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"proposeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proposedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setKycPassed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supplyManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","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":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unsetKycPassed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wipe","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604080518082018252600b81526a23b930b69029b4b63b32b960a91b6020808301919091528251808401845260058152644752414d5360d81b81830152600080546001600160a81b03191633610100810291909117909155845181815294519394919390927f85a8c8100c1d48466310240af79644f50cdae7d09cb4820d60dfc5b2462f0fd0928290030190a1508151620000b590603790602085019062000af3565b508051620000cb90603890602084019062000af3565b50620000d79150503390565b603a80546001600160a01b0319166001600160a01b0392909216919091179055620000ff3390565b603b80546001600160a01b0319166001600160a01b0392909216919091179055620001273390565b603c80546001600160a01b0319166001600160a01b03929092169190911790556200015b6000620001553390565b62000236565b6200016860003362000246565b62000183600080516020620047108339815191523362000246565b6200019e600080516020620047108339815191523362000246565b620001b9600080516020620047108339815191523362000246565b620001d4600080516020620047108339815191523362000246565b620001e0600062000275565b7f7d2e7ebe59ac3e84d466f95497a9bb85eec2f7540273b7c98dfb64d9ed1bf1826200020b6200039e565b6200021562000438565b6000604051620002289392919062000c55565b60405180910390a162000ea0565b62000242828262000449565b5050565b600082815260336020526040902060010154620002648133620004d3565b62000270838362000449565b505050565b603a546001600160a01b0316331480620002b75750620002a260005461010090046001600160a01b031690565b6001600160a01b0316336001600160a01b0316145b620003215760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520737570706c79206d616e616765722063616e2063616c6c60448201526e103a3434b990333ab731ba34b7b71760891b60648201526084015b60405180910390fd5b6200035862000338603a546001600160a01b031690565b620003466012600a62000cf3565b62000352908462000db2565b62000556565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688533604080516001600160a01b039092168252602082018490520160405180910390a150565b606060378054620003af9062000e21565b80601f0160208091040260200160405190810160405280929190818152602001828054620003dd9062000e21565b80156200042e5780601f1062000402576101008083540402835291602001916200042e565b820191906000526020600020905b8154815290600101906020018083116200041057829003601f168201915b5050505050905090565b606060388054620003af9062000e21565b62000455828262000649565b620002425760008281526033602090815260408083206001600160a01b03851684529091529020805460ff191660011790556200048f3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b620004df828262000649565b620002425762000505816001600160a01b031660146200067660201b62001fc81760201c565b6200051b83602062001fc862000676821b17811c565b6040516020016200052e92919062000bc7565b60408051601f198184030181529082905262461bcd60e51b8252620003189160040162000c40565b6001600160a01b038216620005ae5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640162000318565b620005bc6000838362000836565b8060366000828254620005d0919062000c8f565b90915550506001600160a01b03821660009081526034602052604081208054839290620005ff90849062000c8f565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60008281526033602090815260408083206001600160a01b038516845290915290205460ff165b92915050565b606060006200068783600262000db2565b6200069490600262000c8f565b6001600160401b03811115620006ae57620006ae62000e8a565b6040519080825280601f01601f191660200182016040528015620006d9576020820181803683370190505b509050600360fc1b81600081518110620006f757620006f762000e74565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811062000729576200072962000e74565b60200101906001600160f81b031916908160001a90535060006200074f84600262000db2565b6200075c90600162000c8f565b90505b6001811115620007de576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811062000794576200079462000e74565b1a60f81b828281518110620007ad57620007ad62000e74565b60200101906001600160f81b031916908160001a90535060049490941c93620007d68162000e07565b90506200075f565b5083156200082f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000318565b9392505050565b62000851600080516020620046f08339815191523362000649565b15620008c65760405162461bcd60e51b815260206004820152603360248201527f596f7572206163636f756e7420686173206265656e2066726f7a656e2c20636160448201527f6e6e6f742063616c6c2066756e6374696f6e2e00000000000000000000000000606482015260840162000318565b60005460ff16156200090e5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000318565b603a546001600160a01b0384811691161480156200093357506001600160a01b038216155b156200095157620002708383836200027060201b62000c8a1760201c565b603a546001600160a01b0383811691161480156200097657506001600160a01b038316155b156200099457620002708383836200027060201b62000c8a1760201c565b603a546001600160a01b038381169116148015620009c85750620009c8600080516020620046f08339815191528462000649565b8015620009ec57506001600160a01b03831660009081526034602052604090205481145b1562000a0a57620002708383836200027060201b62000c8a1760201c565b62000a158362000ad6565b1562000a645760405162461bcd60e51b815260206004820152601960248201527f53656e646572206163636f756e742069732066726f7a656e2e00000000000000604482015260640162000318565b62000a6f8262000ad6565b1562000abe5760405162461bcd60e51b815260206004820152601b60248201527f5265636569766572206163636f756e742069732066726f7a656e2e0000000000604482015260640162000318565b620002708383836200027060201b62000c8a1760201c565b600062000670600080516020620046f08339815191528362000649565b82805462000b019062000e21565b90600052602060002090601f01602090048101928262000b25576000855562000b70565b82601f1062000b4057805160ff191683800117855562000b70565b8280016001018555821562000b70579182015b8281111562000b7057825182559160200191906001019062000b53565b5062000b7e92915062000b82565b5090565b5b8082111562000b7e576000815560010162000b83565b6000815180845262000bb381602086016020860162000dd4565b601f01601f19169290920160200192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162000c0181601785016020880162000dd4565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835162000c3481602884016020880162000dd4565b01602801949350505050565b6020815260006200082f602083018462000b99565b60608152600062000c6a606083018662000b99565b828103602084015262000c7e818662000b99565b915050826040830152949350505050565b6000821982111562000ca55762000ca562000e5e565b500190565b600181815b8085111562000ceb57816000190482111562000ccf5762000ccf62000e5e565b8085161562000cdd57918102915b93841c939080029062000caf565b509250929050565b60006200082f60ff84168360008262000d0f5750600162000670565b8162000d1e5750600062000670565b816001811462000d37576002811462000d425762000d62565b600191505062000670565b60ff84111562000d565762000d5662000e5e565b50506001821b62000670565b5060208310610133831016604e8410600b841016171562000d87575081810a62000670565b62000d93838362000caa565b806000190482111562000daa5762000daa62000e5e565b029392505050565b600081600019048311821515161562000dcf5762000dcf62000e5e565b500290565b60005b8381101562000df157818101518382015260200162000dd7565b8381111562000e01576000848401525b50505050565b60008162000e195762000e1962000e5e565b506000190190565b600181811c9082168062000e3657607f821691505b6020821081141562000e5857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6138408062000eb06000396000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c80637369eef911610167578063b08ab245116100ce578063dfd7828911610087578063dfd78289146105b3578063e5839836146105c6578063e8573eb9146105d9578063ec1774a2146105ec578063f147389f146105ff578063ff7bce231461061057600080fd5b8063b08ab24514610543578063b5ed298a14610556578063d153b60c14610569578063d547741f1461057a578063dbe72a391461058d578063dd62ed3e146105a057600080fd5b806391d148541161012057806391d14854146104e757806395d89b41146104fa578063a0712d6814610502578063a217fddf14610515578063a457c2d71461051d578063a9059cbb1461053057600080fd5b80637369eef91461046b57806383d3a0801461047e5780638456cb5914610491578063879d3c03146104995780638d1fdf2f146104be5780638da5cb5b146104d157600080fd5b8063313ce5671161020b57806345c8b1a6116101c457806345c8b1a6146103f657806346a8cd5c146104095780634e71e0c81461041c5780635c975abb146104245780636db0b98e1461042f57806370a082311461044257600080fd5b8063313ce5671461039357806336568abe146103a257806339509351146103b55780633f4ba83a146103c8578063410937a5146103d057806342966c68146103e357600080fd5b806318160ddd1161025d57806318160ddd1461031257806318994a53146103245780632159abf41461033757806323b872dd1461034a578063248a9ca31461035d5780632f2ff15d1461038057600080fd5b806301ffc9a71461029a57806306fdde03146102c2578063095ea7b3146102d75780630a1553a5146102ea578063152b8241146102ff575b600080fd5b6102ad6102a83660046130f8565b610621565b60405190151581526020015b60405180910390f35b6102ca610658565b6040516102b99190613352565b6102ad6102e5366004613092565b6106ea565b6102fd6102f8366004613092565b610702565b005b6102fd61030d366004613122565b6107d7565b6036545b6040519081526020016102b9565b610316610332366004612fa2565b61097f565b6102fd610345366004612f18565b6109d9565b6102ad610358366004612f66565b610b51565b61031661036b3660046130bc565b60009081526033602052604090206001015490565b6102fd61038e3660046130d5565b610c64565b604051601281526020016102b9565b6102fd6103b03660046130d5565b610c8f565b6102ad6103c3366004613092565b610d0d565b6102fd610df2565b6102fd6103de366004613092565b610e91565b6102fd6103f13660046130bc565b611021565b6102fd610404366004612f18565b6110e3565b6102fd61041736600461319e565b61118a565b6102fd6112b8565b60005460ff166102ad565b6102fd61043d366004612f18565b61135a565b610316610450366004612f18565b6001600160a01b031660009081526034602052604090205490565b6102fd610479366004612f18565b6114a6565b6102fd61048c366004613016565b6115f7565b6102fd6117d1565b603c546001600160a01b03165b6040516001600160a01b0390911681526020016102b9565b6102fd6104cc366004612f18565b611856565b60005461010090046001600160a01b03166104a6565b6102ad6104f53660046130d5565b6119b5565b6102ca6119e0565b6102fd6105103660046130bc565b6119ef565b610316600081565b6102ad61052b366004613092565b611a9c565b6102ad61053e366004613092565b611b8c565b6102ad610551366004612f18565b611bd0565b6102fd610564366004612f18565b611bea565b6001546001600160a01b03166104a6565b6102fd6105883660046130d5565b611cba565b6102fd61059b366004612f18565b611ce0565b6103166105ae366004612f33565b611e31565b6102fd6105c1366004612f18565b611e5c565b6102ad6105d4366004612f18565b611f03565b6102ad6105e7366004612f18565b611f1d565b6102ad6105fa366004612f18565b611fa6565b603a546001600160a01b03166104a6565b603b546001600160a01b03166104a6565b60006001600160e01b03198216637965db0b60e01b148061065257506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060603780546106679061372d565b80601f01602080910402602001604051908101604052809291908181526020018280546106939061372d565b80156106e05780601f106106b5576101008083540402835291602001916106e0565b820191906000526020600020905b8154815290600101906020018083116106c357829003601f168201915b5050505050905090565b6000336106f881858561216b565b5060019392505050565b61071a6000805160206137eb833981519152336119b5565b61073f5760405162461bcd60e51b8152600401610736906134c6565b60405180910390fd5b6107576000805160206137ab833981519152336119b5565b156107745760405162461bcd60e51b815260040161073690613365565b61077f33838361228f565b61078a33838361216b565b604080513381526001600160a01b03841660208201529081018290527f6e11fb1b7f119e3f2fa29896ef5fdf8b8a2d0d4df6fe90ba8668e7d8b2ffa25e9060600160405180910390a15050565b603a546001600160a01b0316331480610811575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b61082d5760405162461bcd60e51b8152600401610736906133fe565b60005460ff16156108505760405162461bcd60e51b81526004016107369061349c565b61085982611bd0565b6108b95760405162461bcd60e51b815260206004820152602b60248201527f526563697069656e74206163636f756e74207265717569726573204b5943207460448201526a379031b7b73a34b73ab29760a91b6064820152608401610736565b6108c282611f03565b1561090f5760405162461bcd60e51b815260206004820152601c60248201527f526563697069656e74206163636f756e742069732066726f7a656e2e000000006044820152606401610736565b603a54610925906001600160a01b03168261244e565b603a5461093c906001600160a01b03168383612527565b7f1b8f7c4d3ae072e0afc970fed04859899329875fa9715fa37e7da1d9a44f4251848484846040516109719493929190613310565b60405180910390a150505050565b6001600160a01b03831660009081526039602052604080822090516109a5908590613237565b9081526020016040518091039020826040516109c19190613237565b90815260200160405180910390205490509392505050565b603b546001600160a01b0316331480610a13575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b610a2f5760405162461bcd60e51b81526004016107369061355b565b610a3881611f1d565b15610a995760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f7420756e736574204b594320666f722061646d696e69737472617460448201526a37b91030b1b1b7bab73a1760a91b6064820152608401610736565b6001600160a01b038116610af95760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f7420756e736574204b594320666f722061646472657373203078306044820152601760f91b6064820152608401610736565b610b116000805160206137eb83398151915282611cba565b6040516001600160a01b03821681527f8fa3f537534eaa8a497b35f7bd10c9a9e321c8458256eb5048dd35dac0552bb7906020015b60405180910390a150565b6000610b6b6000805160206137eb833981519152336119b5565b610b875760405162461bcd60e51b8152600401610736906134c6565b610b9f6000805160206137ab833981519152336119b5565b15610bbc5760405162461bcd60e51b815260040161073690613365565b6000610bc98585856126b8565b9050836001600160a01b0316856001600160a01b03166000805160206137cb83398151915285604051610bfe91815260200190565b60405180910390a37f6e11fb1b7f119e3f2fa29896ef5fdf8b8a2d0d4df6fe90ba8668e7d8b2ffa25e8533610c338833611e31565b604080516001600160a01b0394851681529390921660208401529082015260600160405180910390a1949350505050565b600082815260336020526040902060010154610c8081336126dc565b610c8a8383612740565b505050565b6001600160a01b0381163314610cff5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610736565b610d0982826127c6565b5050565b6000610d276000805160206137eb833981519152336119b5565b610d435760405162461bcd60e51b8152600401610736906134c6565b610d5b6000805160206137ab833981519152336119b5565b15610d785760405162461bcd60e51b815260040161073690613365565b6000610d8e83610d883387611e31565b9061282d565b9050610d9c335b858361216b565b7f01722f0e92ffd761d4a842cffdd36fe3adb6091e41732a4e714250176b7d8d22335b604080516001600160a01b0392831681529187166020830152810183905260600160405180910390a15060019392505050565b603b546001600160a01b0316331480610e2c575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b610e485760405162461bcd60e51b81526004016107369061355b565b610e50612839565b7faeb196d352664784d1900b0e7414a8face7d29f4dae8c4b0cf68ed477423bbf4335b6040516001600160a01b0390911681526020015b60405180910390a1565b603c546001600160a01b0316331480610ecb575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b610f345760405162461bcd60e51b815260206004820152603460248201527f4f6e6c792074686520456e666f7263656d656e74204d616e616765722063616e6044820152731031b0b636103a3434b990333ab731ba34b7b71760611b6064820152608401610736565b6001600160a01b03821660009081526034602052604090205480821115610fab5760405162461bcd60e51b815260206004820152602560248201527f416d6f756e742063616e6e6f742062652067726561746572207468616e2062616044820152646c616e636560d81b6064820152608401610736565b603a54610fc39084906001600160a01b031684612527565b603a54610fd9906001600160a01b0316836128b3565b604080516001600160a01b0385168152602081018490527f2d2c7da251295f4d722a8ddaf337627952c957ce21b2757c852e47fe81b3a2af91015b60405180910390a1505050565b603a546001600160a01b031633148061105b575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6110775760405162461bcd60e51b8152600401610736906133fe565b603a546110a2906001600160a01b03166110936012600a613609565b61109d90846136b4565b6128b3565b7fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5335b604080516001600160a01b0390921682526020820184905201610b46565b603b546001600160a01b031633148061111d575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6111395760405162461bcd60e51b81526004016107369061355b565b6111516000805160206137ab83398151915282611cba565b6040516001600160a01b03821681527fca5069937e68fd197927055037f59d7c90bf75ac104e6e375539ef480c3ad6ee90602001610b46565b6111a26000805160206137eb833981519152336119b5565b6111be5760405162461bcd60e51b8152600401610736906134c6565b6111d66000805160206137ab833981519152336119b5565b156111f35760405162461bcd60e51b815260040161073690613365565b60005460ff16156112165760405162461bcd60e51b81526004016107369061349c565b61121f33610450565b8111156112785760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f7420617070726f7665206d6f7265207468616e2062616c616e63656044820152601760f91b6064820152608401610736565b6112838383836129fb565b7f6525d8dcd7ef00ad95bfa7dedfbc7fee25fd22d209edbda6370ec3d4d2f8f49c3384848460405161101494939291906132c8565b6001546001600160a01b0316336001600160a01b0316146112eb5760405162461bcd60e51b81526004016107369061344d565b60005461010090046001600160a01b0316611304612a07565b61130f600033612aa9565b6113276000805160206137eb83398151915233610c64565b61133f6000805160206137ab83398151915233611cba565b6113576000805160206137eb83398151915282611cba565b50565b6000546001600160a01b0361010090910416331461138a5760405162461bcd60e51b8152600401610736906133b8565b6001600160a01b0381166113ec5760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f74206368616e676520737570706c79206d616e6167657220746f20604482015263183c181760e11b6064820152608401610736565b603a54611411906000805160206137eb833981519152906001600160a01b0316611cba565b603a80546001600160a01b0319166001600160a01b038316908117909155611448906000805160206137eb83398151915290610c64565b603a5461146d906000805160206137ab833981519152906001600160a01b0316611cba565b6040516001600160a01b03821681527f7a696d744bfa024b93ab3465555620d92fb3b6e9b3f31f73e5cb1b7fdffb297a90602001610b46565b6000546001600160a01b036101009091041633146114d65760405162461bcd60e51b8152600401610736906133b8565b6001600160a01b03811661153d5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f74206368616e676520656e666f7263656d656e74206d616e61676560448201526707220746f203078360c41b6064820152608401610736565b603c54611562906000805160206137eb833981519152906001600160a01b0316611cba565b603c80546001600160a01b0319166001600160a01b038316908117909155611599906000805160206137eb83398151915290610c64565b603c546115be906000805160206137ab833981519152906001600160a01b0316611cba565b6040516001600160a01b03821681527f140f3788a1891d7b9320b7e2925a1f7ad31a9964f5886de7a7ab16c73e52066e90602001610b46565b603a546001600160a01b0316331480611631575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b61164d5760405162461bcd60e51b8152600401610736906133fe565b60005460ff16156116705760405162461bcd60e51b81526004016107369061349c565b61167984611bd0565b6116955760405162461bcd60e51b815260040161073690613512565b61169e84611f03565b156116eb5760405162461bcd60e51b815260206004820152601a60248201527f5370656e646572206163636f756e742069732066726f7a656e2e0000000000006044820152606401610736565b60006116f885858561097f565b90508082111561174a5760405162461bcd60e51b815260206004820152601e60248201527f416d6f756e742067726561746572207468616e20616c6c6f77616e63652e00006044820152606401610736565b603a546117629086906001600160a01b031684612527565b603a54611778906001600160a01b0316836128b3565b61178d8585856117888587612ab3565b612abf565b7f82b004d4752d135ee5f09b127d2f5718853792c19e37a22f66bd8f343e0c9cbc858585856040516117c294939291906132c8565b60405180910390a15050505050565b603b546001600160a01b031633148061180b575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6118275760405162461bcd60e51b81526004016107369061355b565b61182f612bbe565b7f5ee71a369c8672edded508e624ffc9257fa1ae6886ef32905c18e60196bca39933610e73565b603b546001600160a01b0316331480611890575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6118ac5760405162461bcd60e51b81526004016107369061355b565b6118b581611f1d565b1561190e5760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f7420667265657a652061646d696e6973747261746f72206163636f6044820152633ab73a1760e11b6064820152608401610736565b6001600160a01b0381166119645760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f7420667265657a652061646472657373203078302e0000000000006044820152606401610736565b61197c6000805160206137ab83398151915282610c64565b6040516001600160a01b03821681527faf85b60d26151edd11443b704d424da6c43d0468f2235ebae3d1904dbc32304990602001610b46565b60009182526033602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060603880546106679061372d565b603a546001600160a01b0316331480611a29575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b611a455760405162461bcd60e51b8152600401610736906133fe565b611a75611a5a603a546001600160a01b031690565b611a666012600a613609565b611a7090846136b4565b61244e565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885336110c5565b6000611ab66000805160206137eb833981519152336119b5565b611ad25760405162461bcd60e51b8152600401610736906134c6565b611aea6000805160206137ab833981519152336119b5565b15611b075760405162461bcd60e51b815260040161073690613365565b6000611b5a836040518060400160405280601e81526020017f416d6f756e742067726561746572207468616e20616c6c6f77616e63652e0000815250611b53611b4d3390565b88611e31565b9190612c16565b9050611b6533610d95565b7f3fda289a93fbd447987ffc8940a1af71a1fad600cc184d06b56d4aa27139352233610dbf565b6000611b99338484612527565b6040518281526001600160a01b0384169033906000805160206137cb8339815191529060200160405180910390a350600192915050565b60006106526000805160206137eb833981519152836119b5565b6000546001600160a01b03610100909104163314611c1a5760405162461bcd60e51b8152600401610736906133b8565b6001600160a01b038116611c705760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f742070726f706f736520307830206173206e6577206f776e65722e6044820152606401610736565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f4eca5d040b0eaa90931278735a7753956bd8f0424eb2b74279747c62fa7e55c190600090a250565b600082815260336020526040902060010154611cd681336126dc565b610c8a83836127c6565b6000546001600160a01b03610100909104163314611d105760405162461bcd60e51b8152600401610736906133b8565b6001600160a01b038116611d775760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f74206368616e676520636f6d706c69616e6365206d616e61676572604482015267103a3790183c181760c11b6064820152608401610736565b603b54611d9c906000805160206137eb833981519152906001600160a01b0316611cba565b603b80546001600160a01b0319166001600160a01b038316908117909155611dd3906000805160206137eb83398151915290610c64565b603b54611df8906000805160206137ab833981519152906001600160a01b0316611cba565b6040516001600160a01b03821681527f2464dc2a9210ca3b1840dbcd271988b049c111f76b296cbee79f112ad6c2135e90602001610b46565b6001600160a01b03918216600090815260356020908152604080832093909416825291909152205490565b603b546001600160a01b0316331480611e96575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b611eb25760405162461bcd60e51b81526004016107369061355b565b611eca6000805160206137eb83398151915282610c64565b6040516001600160a01b03821681527f0b5df97b96526072100a8af6f1337a7297ec9cdbc3e898e6c808609c815b03ec90602001610b46565b60006106526000805160206137ab833981519152836119b5565b6000611f31603a546001600160a01b031690565b6001600160a01b0316826001600160a01b03161480611f5d5750603b546001600160a01b038381169116145b80611f755750603c546001600160a01b038381169116145b80610652575060005461010090046001600160a01b03166001600160a01b0316826001600160a01b03161492915050565b6000611fb182611bd0565b80156106525750611fc182611f03565b1592915050565b60606000611fd78360026136b4565b611fe29060026135ae565b67ffffffffffffffff811115611ffa57611ffa613794565b6040519080825280601f01601f191660200182016040528015612024576020820181803683370190505b509050600360fc1b8160008151811061203f5761203f61377e565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061206e5761206e61377e565b60200101906001600160f81b031916908160001a90535060006120928460026136b4565b61209d9060016135ae565b90505b6001811115612115576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106120d1576120d161377e565b1a60f81b8282815181106120e7576120e761377e565b60200101906001600160f81b031916908160001a90535060049490941c9361210e81613716565b90506120a0565b5083156121645760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610736565b9392505050565b6001600160a01b0383166121cd5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610736565b6001600160a01b03821661222e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610736565b6001600160a01b0383811660008181526035602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6122a76000805160206137eb833981519152336119b5565b6122c35760405162461bcd60e51b8152600401610736906134c6565b6122db6000805160206137ab833981519152336119b5565b156122f85760405162461bcd60e51b815260040161073690613365565b60005460ff161561231b5760405162461bcd60e51b81526004016107369061349c565b61232482611bd0565b6123405760405162461bcd60e51b815260040161073690613512565b61234983611bd0565b6123a65760405162461bcd60e51b815260206004820152602860248201527f53656e646572206163636f756e74207265717569726573204b594320746f206360448201526737b73a34b73ab29760c11b6064820152608401610736565b6123af82611f03565b156123fc5760405162461bcd60e51b815260206004820152601a60248201527f5370656e646572206163636f756e742069732066726f7a656e2e0000000000006044820152606401610736565b61240583611f03565b15610c8a5760405162461bcd60e51b815260206004820152601960248201527829b2b73232b91030b1b1b7bab73a1034b990333937bd32b71760391b6044820152606401610736565b6001600160a01b0382166124a45760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610736565b6124b060008383612c42565b80603660008282546124c291906135ae565b90915550506001600160a01b038216600090815260346020526040812080548392906124ef9084906135ae565b90915550506040518181526001600160a01b038316906000906000805160206137cb8339815191529060200160405180910390a35050565b6001600160a01b03831661258b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610736565b6001600160a01b0382166125ed5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610736565b6125f8838383612c42565b6001600160a01b038316600090815260346020526040902054818110156126705760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610736565b6001600160a01b038085166000908152603460205260408082208585039055918516815290812080548492906126a79084906135ae565b909155506126b29050565b50505050565b6000336126c6858285612dfb565b6126d1858585612527565b506001949350505050565b6126e682826119b5565b610d09576126fe816001600160a01b03166014611fc8565b612709836020611fc8565b60405160200161271a929190613253565b60408051601f198184030181529082905262461bcd60e51b825261073691600401613352565b61274a82826119b5565b610d095760008281526033602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127823390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127d082826119b5565b15610d095760008281526033602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061216482846135ae565b60005460ff166128825760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610736565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33610e73565b6001600160a01b0382166129135760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610736565b61291f82600083612c42565b6001600160a01b038216600090815260346020526040902054818110156129935760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610736565b6001600160a01b03831660009081526034602052604081208383039055603680548492906129c29084906136d3565b90915550506040518281526000906001600160a01b038516906000805160206137cb8339815191529060200160405180910390a3505050565b610c8a33848484612abf565b6001546001600160a01b0316336001600160a01b031614612a3a5760405162461bcd60e51b81526004016107369061344d565b6001805460008054610100600160a81b0319166101006001600160a01b03808516820292909217928390556001600160a01b031990931690935560405191900490911681527f85a8c8100c1d48466310240af79644f50cdae7d09cb4820d60dfc5b2462f0fd090602001610e87565b610d098282612740565b600061216482846136d3565b33612b0c5760405162461bcd60e51b815260206004820152601d60248201527f417070726f76652066726f6d20746865207a65726f20616464726573730000006044820152606401610736565b6001600160a01b038416612b625760405162461bcd60e51b815260206004820152601c60248201527f417070726f766520666f7220746865207a65726f2061646472657373000000006044820152606401610736565b6001600160a01b038416600090815260396020526040908190209051829190612b8c908690613237565b908152602001604051809103902083604051612ba89190613237565b9081526040519081900360200190205550505050565b60005460ff1615612be15760405162461bcd60e51b81526004016107369061349c565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610e733390565b60008184841115612c3a5760405162461bcd60e51b81526004016107369190613352565b505050900390565b612c5a6000805160206137ab833981519152336119b5565b15612c775760405162461bcd60e51b815260040161073690613365565b60005460ff1615612c9a5760405162461bcd60e51b81526004016107369061349c565b603a546001600160a01b038481169116148015612cbe57506001600160a01b038216155b15612cc857505050565b603a546001600160a01b038381169116148015612cec57506001600160a01b038316155b15612cf657505050565b603a546001600160a01b038381169116148015612d265750612d266000805160206137ab833981519152846119b5565b8015612d4957506001600160a01b03831660009081526034602052604090205481145b15612d5357505050565b612d5c83611f03565b15612da55760405162461bcd60e51b815260206004820152601960248201527829b2b73232b91030b1b1b7bab73a1034b990333937bd32b71760391b6044820152606401610736565b612dae82611f03565b15610c8a5760405162461bcd60e51b815260206004820152601b60248201527f5265636569766572206163636f756e742069732066726f7a656e2e00000000006044820152606401610736565b6000612e078484611e31565b905060001981146126b25781811015612e625760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610736565b6126b2848484840361216b565b80356001600160a01b0381168114612e8657600080fd5b919050565b600082601f830112612e9c57600080fd5b813567ffffffffffffffff80821115612eb757612eb7613794565b604051601f8301601f19908116603f01168101908282118183101715612edf57612edf613794565b81604052838152866020858801011115612ef857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f2a57600080fd5b61216482612e6f565b60008060408385031215612f4657600080fd5b612f4f83612e6f565b9150612f5d60208401612e6f565b90509250929050565b600080600060608486031215612f7b57600080fd5b612f8484612e6f565b9250612f9260208501612e6f565b9150604084013590509250925092565b600080600060608486031215612fb757600080fd5b612fc084612e6f565b9250602084013567ffffffffffffffff80821115612fdd57600080fd5b612fe987838801612e8b565b93506040860135915080821115612fff57600080fd5b5061300c86828701612e8b565b9150509250925092565b6000806000806080858703121561302c57600080fd5b61303585612e6f565b9350602085013567ffffffffffffffff8082111561305257600080fd5b61305e88838901612e8b565b9450604087013591508082111561307457600080fd5b5061308187828801612e8b565b949793965093946060013593505050565b600080604083850312156130a557600080fd5b6130ae83612e6f565b946020939093013593505050565b6000602082840312156130ce57600080fd5b5035919050565b600080604083850312156130e857600080fd5b82359150612f5d60208401612e6f565b60006020828403121561310a57600080fd5b81356001600160e01b03198116811461216457600080fd5b6000806000806080858703121561313857600080fd5b843567ffffffffffffffff8082111561315057600080fd5b61315c88838901612e8b565b9550602087013591508082111561317257600080fd5b5061317f87828801612e8b565b93505061318e60408601612e6f565b9396929550929360600135925050565b6000806000606084860312156131b357600080fd5b833567ffffffffffffffff808211156131cb57600080fd5b6131d787838801612e8b565b945060208601359150808211156131ed57600080fd5b506131fa86828701612e8b565b925050604084013590509250925092565b600081518084526132238160208601602086016136ea565b601f01601f19169290920160200192915050565b600082516132498184602087016136ea565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161328b8160178501602088016136ea565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516132bc8160288401602088016136ea565b01602801949350505050565b6001600160a01b03851681526080602082018190526000906132ec9083018661320b565b82810360408401526132fe818661320b565b91505082606083015295945050505050565b608081526000613323608083018761320b565b8281036020840152613335818761320b565b6001600160a01b0395909516604084015250506060015292915050565b602081526000612164602083018461320b565b60208082526033908201527f596f7572206163636f756e7420686173206265656e2066726f7a656e2c206361604082015272373737ba1031b0b63610333ab731ba34b7b71760691b606082015260800190565b60208082526026908201527f4f6e6c7920746865206f776e65722063616e2063616c6c20746869732066756e60408201526531ba34b7b71760d11b606082015260800190565b6020808252602f908201527f4f6e6c792074686520737570706c79206d616e616765722063616e2063616c6c60408201526e103a3434b990333ab731ba34b7b71760891b606082015260800190565b6020808252602f908201527f4f6e6c79207468652070726f706f736564206f776e65722063616e2063616c6c60408201526e103a3434b990333ab731ba34b7b71760891b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252602c908201527f43616c6c696e6720746869732066756e6374696f6e207265717569726573204b60408201526b2ca19030b8383937bb30b61760a11b606082015260800190565b60208082526029908201527f5370656e646572206163636f756e74207265717569726573204b594320746f2060408201526831b7b73a34b73ab29760b91b606082015260800190565b60208082526033908201527f4f6e6c792074686520436f6d706c69616e6365204d616e616765722063616e2060408201527231b0b636103a3434b990333ab731ba34b7b71760691b606082015260800190565b600082198211156135c1576135c1613768565b500190565b600181815b808511156136015781600019048211156135e7576135e7613768565b808516156135f457918102915b93841c93908002906135cb565b509250929050565b600061216460ff84168360008261362257506001610652565b8161362f57506000610652565b8160018114613645576002811461364f5761366b565b6001915050610652565b60ff84111561366057613660613768565b50506001821b610652565b5060208310610133831016604e8410600b841016171561368e575081810a610652565b61369883836135c6565b80600019048211156136ac576136ac613768565b029392505050565b60008160001904831182151516156136ce576136ce613768565b500290565b6000828210156136e5576136e5613768565b500390565b60005b838110156137055781810151838201526020016136ed565b838111156126b25750506000910152565b60008161372557613725613768565b506000190190565b600181811c9082168061374157607f821691505b6020821081141561376257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe7c78561e9c3b6dc2802172fb2041fc3504da930f63dfaf87b57359e924c17eb9ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8198966b374d1cbb64517af77c9cfe1776304682a02cfc0e8c918a5a94969ef8a2646970667358221220cafefe73ea83f697c038b8afc7fab198549d941731a708ca56a8da44920c3fca64736f6c634300080700337c78561e9c3b6dc2802172fb2041fc3504da930f63dfaf87b57359e924c17eb98198966b374d1cbb64517af77c9cfe1776304682a02cfc0e8c918a5a94969ef8

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102955760003560e01c80637369eef911610167578063b08ab245116100ce578063dfd7828911610087578063dfd78289146105b3578063e5839836146105c6578063e8573eb9146105d9578063ec1774a2146105ec578063f147389f146105ff578063ff7bce231461061057600080fd5b8063b08ab24514610543578063b5ed298a14610556578063d153b60c14610569578063d547741f1461057a578063dbe72a391461058d578063dd62ed3e146105a057600080fd5b806391d148541161012057806391d14854146104e757806395d89b41146104fa578063a0712d6814610502578063a217fddf14610515578063a457c2d71461051d578063a9059cbb1461053057600080fd5b80637369eef91461046b57806383d3a0801461047e5780638456cb5914610491578063879d3c03146104995780638d1fdf2f146104be5780638da5cb5b146104d157600080fd5b8063313ce5671161020b57806345c8b1a6116101c457806345c8b1a6146103f657806346a8cd5c146104095780634e71e0c81461041c5780635c975abb146104245780636db0b98e1461042f57806370a082311461044257600080fd5b8063313ce5671461039357806336568abe146103a257806339509351146103b55780633f4ba83a146103c8578063410937a5146103d057806342966c68146103e357600080fd5b806318160ddd1161025d57806318160ddd1461031257806318994a53146103245780632159abf41461033757806323b872dd1461034a578063248a9ca31461035d5780632f2ff15d1461038057600080fd5b806301ffc9a71461029a57806306fdde03146102c2578063095ea7b3146102d75780630a1553a5146102ea578063152b8241146102ff575b600080fd5b6102ad6102a83660046130f8565b610621565b60405190151581526020015b60405180910390f35b6102ca610658565b6040516102b99190613352565b6102ad6102e5366004613092565b6106ea565b6102fd6102f8366004613092565b610702565b005b6102fd61030d366004613122565b6107d7565b6036545b6040519081526020016102b9565b610316610332366004612fa2565b61097f565b6102fd610345366004612f18565b6109d9565b6102ad610358366004612f66565b610b51565b61031661036b3660046130bc565b60009081526033602052604090206001015490565b6102fd61038e3660046130d5565b610c64565b604051601281526020016102b9565b6102fd6103b03660046130d5565b610c8f565b6102ad6103c3366004613092565b610d0d565b6102fd610df2565b6102fd6103de366004613092565b610e91565b6102fd6103f13660046130bc565b611021565b6102fd610404366004612f18565b6110e3565b6102fd61041736600461319e565b61118a565b6102fd6112b8565b60005460ff166102ad565b6102fd61043d366004612f18565b61135a565b610316610450366004612f18565b6001600160a01b031660009081526034602052604090205490565b6102fd610479366004612f18565b6114a6565b6102fd61048c366004613016565b6115f7565b6102fd6117d1565b603c546001600160a01b03165b6040516001600160a01b0390911681526020016102b9565b6102fd6104cc366004612f18565b611856565b60005461010090046001600160a01b03166104a6565b6102ad6104f53660046130d5565b6119b5565b6102ca6119e0565b6102fd6105103660046130bc565b6119ef565b610316600081565b6102ad61052b366004613092565b611a9c565b6102ad61053e366004613092565b611b8c565b6102ad610551366004612f18565b611bd0565b6102fd610564366004612f18565b611bea565b6001546001600160a01b03166104a6565b6102fd6105883660046130d5565b611cba565b6102fd61059b366004612f18565b611ce0565b6103166105ae366004612f33565b611e31565b6102fd6105c1366004612f18565b611e5c565b6102ad6105d4366004612f18565b611f03565b6102ad6105e7366004612f18565b611f1d565b6102ad6105fa366004612f18565b611fa6565b603a546001600160a01b03166104a6565b603b546001600160a01b03166104a6565b60006001600160e01b03198216637965db0b60e01b148061065257506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060603780546106679061372d565b80601f01602080910402602001604051908101604052809291908181526020018280546106939061372d565b80156106e05780601f106106b5576101008083540402835291602001916106e0565b820191906000526020600020905b8154815290600101906020018083116106c357829003601f168201915b5050505050905090565b6000336106f881858561216b565b5060019392505050565b61071a6000805160206137eb833981519152336119b5565b61073f5760405162461bcd60e51b8152600401610736906134c6565b60405180910390fd5b6107576000805160206137ab833981519152336119b5565b156107745760405162461bcd60e51b815260040161073690613365565b61077f33838361228f565b61078a33838361216b565b604080513381526001600160a01b03841660208201529081018290527f6e11fb1b7f119e3f2fa29896ef5fdf8b8a2d0d4df6fe90ba8668e7d8b2ffa25e9060600160405180910390a15050565b603a546001600160a01b0316331480610811575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b61082d5760405162461bcd60e51b8152600401610736906133fe565b60005460ff16156108505760405162461bcd60e51b81526004016107369061349c565b61085982611bd0565b6108b95760405162461bcd60e51b815260206004820152602b60248201527f526563697069656e74206163636f756e74207265717569726573204b5943207460448201526a379031b7b73a34b73ab29760a91b6064820152608401610736565b6108c282611f03565b1561090f5760405162461bcd60e51b815260206004820152601c60248201527f526563697069656e74206163636f756e742069732066726f7a656e2e000000006044820152606401610736565b603a54610925906001600160a01b03168261244e565b603a5461093c906001600160a01b03168383612527565b7f1b8f7c4d3ae072e0afc970fed04859899329875fa9715fa37e7da1d9a44f4251848484846040516109719493929190613310565b60405180910390a150505050565b6001600160a01b03831660009081526039602052604080822090516109a5908590613237565b9081526020016040518091039020826040516109c19190613237565b90815260200160405180910390205490509392505050565b603b546001600160a01b0316331480610a13575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b610a2f5760405162461bcd60e51b81526004016107369061355b565b610a3881611f1d565b15610a995760405162461bcd60e51b815260206004820152602b60248201527f43616e6e6f7420756e736574204b594320666f722061646d696e69737472617460448201526a37b91030b1b1b7bab73a1760a91b6064820152608401610736565b6001600160a01b038116610af95760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f7420756e736574204b594320666f722061646472657373203078306044820152601760f91b6064820152608401610736565b610b116000805160206137eb83398151915282611cba565b6040516001600160a01b03821681527f8fa3f537534eaa8a497b35f7bd10c9a9e321c8458256eb5048dd35dac0552bb7906020015b60405180910390a150565b6000610b6b6000805160206137eb833981519152336119b5565b610b875760405162461bcd60e51b8152600401610736906134c6565b610b9f6000805160206137ab833981519152336119b5565b15610bbc5760405162461bcd60e51b815260040161073690613365565b6000610bc98585856126b8565b9050836001600160a01b0316856001600160a01b03166000805160206137cb83398151915285604051610bfe91815260200190565b60405180910390a37f6e11fb1b7f119e3f2fa29896ef5fdf8b8a2d0d4df6fe90ba8668e7d8b2ffa25e8533610c338833611e31565b604080516001600160a01b0394851681529390921660208401529082015260600160405180910390a1949350505050565b600082815260336020526040902060010154610c8081336126dc565b610c8a8383612740565b505050565b6001600160a01b0381163314610cff5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610736565b610d0982826127c6565b5050565b6000610d276000805160206137eb833981519152336119b5565b610d435760405162461bcd60e51b8152600401610736906134c6565b610d5b6000805160206137ab833981519152336119b5565b15610d785760405162461bcd60e51b815260040161073690613365565b6000610d8e83610d883387611e31565b9061282d565b9050610d9c335b858361216b565b7f01722f0e92ffd761d4a842cffdd36fe3adb6091e41732a4e714250176b7d8d22335b604080516001600160a01b0392831681529187166020830152810183905260600160405180910390a15060019392505050565b603b546001600160a01b0316331480610e2c575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b610e485760405162461bcd60e51b81526004016107369061355b565b610e50612839565b7faeb196d352664784d1900b0e7414a8face7d29f4dae8c4b0cf68ed477423bbf4335b6040516001600160a01b0390911681526020015b60405180910390a1565b603c546001600160a01b0316331480610ecb575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b610f345760405162461bcd60e51b815260206004820152603460248201527f4f6e6c792074686520456e666f7263656d656e74204d616e616765722063616e6044820152731031b0b636103a3434b990333ab731ba34b7b71760611b6064820152608401610736565b6001600160a01b03821660009081526034602052604090205480821115610fab5760405162461bcd60e51b815260206004820152602560248201527f416d6f756e742063616e6e6f742062652067726561746572207468616e2062616044820152646c616e636560d81b6064820152608401610736565b603a54610fc39084906001600160a01b031684612527565b603a54610fd9906001600160a01b0316836128b3565b604080516001600160a01b0385168152602081018490527f2d2c7da251295f4d722a8ddaf337627952c957ce21b2757c852e47fe81b3a2af91015b60405180910390a1505050565b603a546001600160a01b031633148061105b575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6110775760405162461bcd60e51b8152600401610736906133fe565b603a546110a2906001600160a01b03166110936012600a613609565b61109d90846136b4565b6128b3565b7fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5335b604080516001600160a01b0390921682526020820184905201610b46565b603b546001600160a01b031633148061111d575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6111395760405162461bcd60e51b81526004016107369061355b565b6111516000805160206137ab83398151915282611cba565b6040516001600160a01b03821681527fca5069937e68fd197927055037f59d7c90bf75ac104e6e375539ef480c3ad6ee90602001610b46565b6111a26000805160206137eb833981519152336119b5565b6111be5760405162461bcd60e51b8152600401610736906134c6565b6111d66000805160206137ab833981519152336119b5565b156111f35760405162461bcd60e51b815260040161073690613365565b60005460ff16156112165760405162461bcd60e51b81526004016107369061349c565b61121f33610450565b8111156112785760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f7420617070726f7665206d6f7265207468616e2062616c616e63656044820152601760f91b6064820152608401610736565b6112838383836129fb565b7f6525d8dcd7ef00ad95bfa7dedfbc7fee25fd22d209edbda6370ec3d4d2f8f49c3384848460405161101494939291906132c8565b6001546001600160a01b0316336001600160a01b0316146112eb5760405162461bcd60e51b81526004016107369061344d565b60005461010090046001600160a01b0316611304612a07565b61130f600033612aa9565b6113276000805160206137eb83398151915233610c64565b61133f6000805160206137ab83398151915233611cba565b6113576000805160206137eb83398151915282611cba565b50565b6000546001600160a01b0361010090910416331461138a5760405162461bcd60e51b8152600401610736906133b8565b6001600160a01b0381166113ec5760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f74206368616e676520737570706c79206d616e6167657220746f20604482015263183c181760e11b6064820152608401610736565b603a54611411906000805160206137eb833981519152906001600160a01b0316611cba565b603a80546001600160a01b0319166001600160a01b038316908117909155611448906000805160206137eb83398151915290610c64565b603a5461146d906000805160206137ab833981519152906001600160a01b0316611cba565b6040516001600160a01b03821681527f7a696d744bfa024b93ab3465555620d92fb3b6e9b3f31f73e5cb1b7fdffb297a90602001610b46565b6000546001600160a01b036101009091041633146114d65760405162461bcd60e51b8152600401610736906133b8565b6001600160a01b03811661153d5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f74206368616e676520656e666f7263656d656e74206d616e61676560448201526707220746f203078360c41b6064820152608401610736565b603c54611562906000805160206137eb833981519152906001600160a01b0316611cba565b603c80546001600160a01b0319166001600160a01b038316908117909155611599906000805160206137eb83398151915290610c64565b603c546115be906000805160206137ab833981519152906001600160a01b0316611cba565b6040516001600160a01b03821681527f140f3788a1891d7b9320b7e2925a1f7ad31a9964f5886de7a7ab16c73e52066e90602001610b46565b603a546001600160a01b0316331480611631575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b61164d5760405162461bcd60e51b8152600401610736906133fe565b60005460ff16156116705760405162461bcd60e51b81526004016107369061349c565b61167984611bd0565b6116955760405162461bcd60e51b815260040161073690613512565b61169e84611f03565b156116eb5760405162461bcd60e51b815260206004820152601a60248201527f5370656e646572206163636f756e742069732066726f7a656e2e0000000000006044820152606401610736565b60006116f885858561097f565b90508082111561174a5760405162461bcd60e51b815260206004820152601e60248201527f416d6f756e742067726561746572207468616e20616c6c6f77616e63652e00006044820152606401610736565b603a546117629086906001600160a01b031684612527565b603a54611778906001600160a01b0316836128b3565b61178d8585856117888587612ab3565b612abf565b7f82b004d4752d135ee5f09b127d2f5718853792c19e37a22f66bd8f343e0c9cbc858585856040516117c294939291906132c8565b60405180910390a15050505050565b603b546001600160a01b031633148061180b575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6118275760405162461bcd60e51b81526004016107369061355b565b61182f612bbe565b7f5ee71a369c8672edded508e624ffc9257fa1ae6886ef32905c18e60196bca39933610e73565b603b546001600160a01b0316331480611890575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6118ac5760405162461bcd60e51b81526004016107369061355b565b6118b581611f1d565b1561190e5760405162461bcd60e51b8152602060048201526024808201527f43616e6e6f7420667265657a652061646d696e6973747261746f72206163636f6044820152633ab73a1760e11b6064820152608401610736565b6001600160a01b0381166119645760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f7420667265657a652061646472657373203078302e0000000000006044820152606401610736565b61197c6000805160206137ab83398151915282610c64565b6040516001600160a01b03821681527faf85b60d26151edd11443b704d424da6c43d0468f2235ebae3d1904dbc32304990602001610b46565b60009182526033602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060603880546106679061372d565b603a546001600160a01b0316331480611a29575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b611a455760405162461bcd60e51b8152600401610736906133fe565b611a75611a5a603a546001600160a01b031690565b611a666012600a613609565b611a7090846136b4565b61244e565b7f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885336110c5565b6000611ab66000805160206137eb833981519152336119b5565b611ad25760405162461bcd60e51b8152600401610736906134c6565b611aea6000805160206137ab833981519152336119b5565b15611b075760405162461bcd60e51b815260040161073690613365565b6000611b5a836040518060400160405280601e81526020017f416d6f756e742067726561746572207468616e20616c6c6f77616e63652e0000815250611b53611b4d3390565b88611e31565b9190612c16565b9050611b6533610d95565b7f3fda289a93fbd447987ffc8940a1af71a1fad600cc184d06b56d4aa27139352233610dbf565b6000611b99338484612527565b6040518281526001600160a01b0384169033906000805160206137cb8339815191529060200160405180910390a350600192915050565b60006106526000805160206137eb833981519152836119b5565b6000546001600160a01b03610100909104163314611c1a5760405162461bcd60e51b8152600401610736906133b8565b6001600160a01b038116611c705760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f742070726f706f736520307830206173206e6577206f776e65722e6044820152606401610736565b600180546001600160a01b0319166001600160a01b0383169081179091556040517f4eca5d040b0eaa90931278735a7753956bd8f0424eb2b74279747c62fa7e55c190600090a250565b600082815260336020526040902060010154611cd681336126dc565b610c8a83836127c6565b6000546001600160a01b03610100909104163314611d105760405162461bcd60e51b8152600401610736906133b8565b6001600160a01b038116611d775760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f74206368616e676520636f6d706c69616e6365206d616e61676572604482015267103a3790183c181760c11b6064820152608401610736565b603b54611d9c906000805160206137eb833981519152906001600160a01b0316611cba565b603b80546001600160a01b0319166001600160a01b038316908117909155611dd3906000805160206137eb83398151915290610c64565b603b54611df8906000805160206137ab833981519152906001600160a01b0316611cba565b6040516001600160a01b03821681527f2464dc2a9210ca3b1840dbcd271988b049c111f76b296cbee79f112ad6c2135e90602001610b46565b6001600160a01b03918216600090815260356020908152604080832093909416825291909152205490565b603b546001600160a01b0316331480611e96575060005461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b611eb25760405162461bcd60e51b81526004016107369061355b565b611eca6000805160206137eb83398151915282610c64565b6040516001600160a01b03821681527f0b5df97b96526072100a8af6f1337a7297ec9cdbc3e898e6c808609c815b03ec90602001610b46565b60006106526000805160206137ab833981519152836119b5565b6000611f31603a546001600160a01b031690565b6001600160a01b0316826001600160a01b03161480611f5d5750603b546001600160a01b038381169116145b80611f755750603c546001600160a01b038381169116145b80610652575060005461010090046001600160a01b03166001600160a01b0316826001600160a01b03161492915050565b6000611fb182611bd0565b80156106525750611fc182611f03565b1592915050565b60606000611fd78360026136b4565b611fe29060026135ae565b67ffffffffffffffff811115611ffa57611ffa613794565b6040519080825280601f01601f191660200182016040528015612024576020820181803683370190505b509050600360fc1b8160008151811061203f5761203f61377e565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061206e5761206e61377e565b60200101906001600160f81b031916908160001a90535060006120928460026136b4565b61209d9060016135ae565b90505b6001811115612115576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106120d1576120d161377e565b1a60f81b8282815181106120e7576120e761377e565b60200101906001600160f81b031916908160001a90535060049490941c9361210e81613716565b90506120a0565b5083156121645760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610736565b9392505050565b6001600160a01b0383166121cd5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610736565b6001600160a01b03821661222e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610736565b6001600160a01b0383811660008181526035602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6122a76000805160206137eb833981519152336119b5565b6122c35760405162461bcd60e51b8152600401610736906134c6565b6122db6000805160206137ab833981519152336119b5565b156122f85760405162461bcd60e51b815260040161073690613365565b60005460ff161561231b5760405162461bcd60e51b81526004016107369061349c565b61232482611bd0565b6123405760405162461bcd60e51b815260040161073690613512565b61234983611bd0565b6123a65760405162461bcd60e51b815260206004820152602860248201527f53656e646572206163636f756e74207265717569726573204b594320746f206360448201526737b73a34b73ab29760c11b6064820152608401610736565b6123af82611f03565b156123fc5760405162461bcd60e51b815260206004820152601a60248201527f5370656e646572206163636f756e742069732066726f7a656e2e0000000000006044820152606401610736565b61240583611f03565b15610c8a5760405162461bcd60e51b815260206004820152601960248201527829b2b73232b91030b1b1b7bab73a1034b990333937bd32b71760391b6044820152606401610736565b6001600160a01b0382166124a45760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610736565b6124b060008383612c42565b80603660008282546124c291906135ae565b90915550506001600160a01b038216600090815260346020526040812080548392906124ef9084906135ae565b90915550506040518181526001600160a01b038316906000906000805160206137cb8339815191529060200160405180910390a35050565b6001600160a01b03831661258b5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610736565b6001600160a01b0382166125ed5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610736565b6125f8838383612c42565b6001600160a01b038316600090815260346020526040902054818110156126705760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610736565b6001600160a01b038085166000908152603460205260408082208585039055918516815290812080548492906126a79084906135ae565b909155506126b29050565b50505050565b6000336126c6858285612dfb565b6126d1858585612527565b506001949350505050565b6126e682826119b5565b610d09576126fe816001600160a01b03166014611fc8565b612709836020611fc8565b60405160200161271a929190613253565b60408051601f198184030181529082905262461bcd60e51b825261073691600401613352565b61274a82826119b5565b610d095760008281526033602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127823390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127d082826119b5565b15610d095760008281526033602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061216482846135ae565b60005460ff166128825760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610736565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa33610e73565b6001600160a01b0382166129135760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610736565b61291f82600083612c42565b6001600160a01b038216600090815260346020526040902054818110156129935760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610736565b6001600160a01b03831660009081526034602052604081208383039055603680548492906129c29084906136d3565b90915550506040518281526000906001600160a01b038516906000805160206137cb8339815191529060200160405180910390a3505050565b610c8a33848484612abf565b6001546001600160a01b0316336001600160a01b031614612a3a5760405162461bcd60e51b81526004016107369061344d565b6001805460008054610100600160a81b0319166101006001600160a01b03808516820292909217928390556001600160a01b031990931690935560405191900490911681527f85a8c8100c1d48466310240af79644f50cdae7d09cb4820d60dfc5b2462f0fd090602001610e87565b610d098282612740565b600061216482846136d3565b33612b0c5760405162461bcd60e51b815260206004820152601d60248201527f417070726f76652066726f6d20746865207a65726f20616464726573730000006044820152606401610736565b6001600160a01b038416612b625760405162461bcd60e51b815260206004820152601c60248201527f417070726f766520666f7220746865207a65726f2061646472657373000000006044820152606401610736565b6001600160a01b038416600090815260396020526040908190209051829190612b8c908690613237565b908152602001604051809103902083604051612ba89190613237565b9081526040519081900360200190205550505050565b60005460ff1615612be15760405162461bcd60e51b81526004016107369061349c565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610e733390565b60008184841115612c3a5760405162461bcd60e51b81526004016107369190613352565b505050900390565b612c5a6000805160206137ab833981519152336119b5565b15612c775760405162461bcd60e51b815260040161073690613365565b60005460ff1615612c9a5760405162461bcd60e51b81526004016107369061349c565b603a546001600160a01b038481169116148015612cbe57506001600160a01b038216155b15612cc857505050565b603a546001600160a01b038381169116148015612cec57506001600160a01b038316155b15612cf657505050565b603a546001600160a01b038381169116148015612d265750612d266000805160206137ab833981519152846119b5565b8015612d4957506001600160a01b03831660009081526034602052604090205481145b15612d5357505050565b612d5c83611f03565b15612da55760405162461bcd60e51b815260206004820152601960248201527829b2b73232b91030b1b1b7bab73a1034b990333937bd32b71760391b6044820152606401610736565b612dae82611f03565b15610c8a5760405162461bcd60e51b815260206004820152601b60248201527f5265636569766572206163636f756e742069732066726f7a656e2e00000000006044820152606401610736565b6000612e078484611e31565b905060001981146126b25781811015612e625760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610736565b6126b2848484840361216b565b80356001600160a01b0381168114612e8657600080fd5b919050565b600082601f830112612e9c57600080fd5b813567ffffffffffffffff80821115612eb757612eb7613794565b604051601f8301601f19908116603f01168101908282118183101715612edf57612edf613794565b81604052838152866020858801011115612ef857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f2a57600080fd5b61216482612e6f565b60008060408385031215612f4657600080fd5b612f4f83612e6f565b9150612f5d60208401612e6f565b90509250929050565b600080600060608486031215612f7b57600080fd5b612f8484612e6f565b9250612f9260208501612e6f565b9150604084013590509250925092565b600080600060608486031215612fb757600080fd5b612fc084612e6f565b9250602084013567ffffffffffffffff80821115612fdd57600080fd5b612fe987838801612e8b565b93506040860135915080821115612fff57600080fd5b5061300c86828701612e8b565b9150509250925092565b6000806000806080858703121561302c57600080fd5b61303585612e6f565b9350602085013567ffffffffffffffff8082111561305257600080fd5b61305e88838901612e8b565b9450604087013591508082111561307457600080fd5b5061308187828801612e8b565b949793965093946060013593505050565b600080604083850312156130a557600080fd5b6130ae83612e6f565b946020939093013593505050565b6000602082840312156130ce57600080fd5b5035919050565b600080604083850312156130e857600080fd5b82359150612f5d60208401612e6f565b60006020828403121561310a57600080fd5b81356001600160e01b03198116811461216457600080fd5b6000806000806080858703121561313857600080fd5b843567ffffffffffffffff8082111561315057600080fd5b61315c88838901612e8b565b9550602087013591508082111561317257600080fd5b5061317f87828801612e8b565b93505061318e60408601612e6f565b9396929550929360600135925050565b6000806000606084860312156131b357600080fd5b833567ffffffffffffffff808211156131cb57600080fd5b6131d787838801612e8b565b945060208601359150808211156131ed57600080fd5b506131fa86828701612e8b565b925050604084013590509250925092565b600081518084526132238160208601602086016136ea565b601f01601f19169290920160200192915050565b600082516132498184602087016136ea565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161328b8160178501602088016136ea565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516132bc8160288401602088016136ea565b01602801949350505050565b6001600160a01b03851681526080602082018190526000906132ec9083018661320b565b82810360408401526132fe818661320b565b91505082606083015295945050505050565b608081526000613323608083018761320b565b8281036020840152613335818761320b565b6001600160a01b0395909516604084015250506060015292915050565b602081526000612164602083018461320b565b60208082526033908201527f596f7572206163636f756e7420686173206265656e2066726f7a656e2c206361604082015272373737ba1031b0b63610333ab731ba34b7b71760691b606082015260800190565b60208082526026908201527f4f6e6c7920746865206f776e65722063616e2063616c6c20746869732066756e60408201526531ba34b7b71760d11b606082015260800190565b6020808252602f908201527f4f6e6c792074686520737570706c79206d616e616765722063616e2063616c6c60408201526e103a3434b990333ab731ba34b7b71760891b606082015260800190565b6020808252602f908201527f4f6e6c79207468652070726f706f736564206f776e65722063616e2063616c6c60408201526e103a3434b990333ab731ba34b7b71760891b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b6020808252602c908201527f43616c6c696e6720746869732066756e6374696f6e207265717569726573204b60408201526b2ca19030b8383937bb30b61760a11b606082015260800190565b60208082526029908201527f5370656e646572206163636f756e74207265717569726573204b594320746f2060408201526831b7b73a34b73ab29760b91b606082015260800190565b60208082526033908201527f4f6e6c792074686520436f6d706c69616e6365204d616e616765722063616e2060408201527231b0b636103a3434b990333ab731ba34b7b71760691b606082015260800190565b600082198211156135c1576135c1613768565b500190565b600181815b808511156136015781600019048211156135e7576135e7613768565b808516156135f457918102915b93841c93908002906135cb565b509250929050565b600061216460ff84168360008261362257506001610652565b8161362f57506000610652565b8160018114613645576002811461364f5761366b565b6001915050610652565b60ff84111561366057613660613768565b50506001821b610652565b5060208310610133831016604e8410600b841016171561368e575081810a610652565b61369883836135c6565b80600019048211156136ac576136ac613768565b029392505050565b60008160001904831182151516156136ce576136ce613768565b500290565b6000828210156136e5576136e5613768565b500390565b60005b838110156137055781810151838201526020016136ed565b838111156126b25750506000910152565b60008161372557613725613768565b506000190190565b600181811c9082168061374157607f821691505b6020821081141561376257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe7c78561e9c3b6dc2802172fb2041fc3504da930f63dfaf87b57359e924c17eb9ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8198966b374d1cbb64517af77c9cfe1776304682a02cfc0e8c918a5a94969ef8a2646970667358221220cafefe73ea83f697c038b8afc7fab198549d941731a708ca56a8da44920c3fca64736f6c63430008070033

Deployed Bytecode Sourcemap

44987:15444:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37618:204;;;;;;:::i;:::-;;:::i;:::-;;;8690:14:1;;8683:22;8665:41;;8653:2;8638:18;37618:204:0;;;;;;;;24276:100;;;:::i;:::-;;;;;;;:::i;26627:201::-;;;;;;:::i;:::-;;:::i;59154:309::-;;;;;;:::i;:::-;;:::i;:::-;;57520:533;;;;;;:::i;:::-;;:::i;25396:108::-;25484:12;;25396:108;;;8863:25:1;;;8851:2;8836:18;25396:108:0;8717:177:1;20598:245:0;;;;;;:::i;:::-;;:::i;51458:367::-;;;;;;:::i;:::-;;:::i;58743:377::-;;;;;;:::i;:::-;;:::i;39045:131::-;;;;;;:::i;:::-;39119:7;39146:12;;;:6;:12;;;;;:22;;;;39045:131;39438:147;;;;;;:::i;:::-;;:::i;25238:93::-;;;25321:2;26028:36:1;;26016:2;26001:18;25238:93:0;25886:184:1;40486:218:0;;;;;;:::i;:::-;;:::i;59498:412::-;;;;;;:::i;:::-;;:::i;53104:114::-;;;:::i;53631:383::-;;;;;;:::i;:::-;;:::i;54259:164::-;;;;;;:::i;:::-;;:::i;52594:143::-;;;;;;:::i;:::-;;:::i;56044:638::-;;;;;;:::i;:::-;;:::i;53250:360::-;;;:::i;43735:86::-;43782:4;43806:7;;;43735:86;;48429:446;;;;;;:::i;:::-;;:::i;25567:127::-;;;;;;:::i;:::-;-1:-1:-1;;;;;25668:18:0;25641:7;25668:18;;;:9;:18;;;;;;;25567:127;50101:523;;;;;;:::i;:::-;;:::i;56690:822::-;;;;;;:::i;:::-;;:::i;52963:108::-;;;:::i;49750:105::-;49828:19;;-1:-1:-1;;;;;49828:19:0;49750:105;;;-1:-1:-1;;;;;7268:32:1;;;7250:51;;7238:2;7223:18;49750:105:0;7104:203:1;52217:332:0;;;;;;:::i;:::-;;:::i;19126:79::-;19164:7;19191:6;;;;-1:-1:-1;;;;;19191:6:0;19126:79;;37914:147;;;;;;:::i;:::-;;:::i;24495:104::-;;;:::i;54072:166::-;;;;;;:::i;:::-;;:::i;37005:49::-;;37050:4;37005:49;;59945:483;;;;;;:::i;:::-;;:::i;55708:217::-;;;;;;:::i;:::-;;:::i;51094:119::-;;;;;;:::i;:::-;;:::i;19787:223::-;;;;;;:::i;:::-;;:::i;19213:95::-;19286:14;;-1:-1:-1;;;;;19286:14:0;19213:95;;39830:149;;;;;;:::i;:::-;;:::i;49229:513::-;;;;;;:::i;:::-;;:::i;26156:151::-;;;;;;:::i;:::-;;:::i;51242:154::-;;;;;;:::i;:::-;;:::i;52032:112::-;;;;;;:::i;:::-;;:::i;50632:265::-;;;;;;:::i;:::-;;:::i;52790:142::-;;;;;;:::i;:::-;;:::i;48103:95::-;48176:14;;-1:-1:-1;;;;;48176:14:0;48103:95;;48883:103;48960:18;;-1:-1:-1;;;;;48960:18:0;48883:103;;37618:204;37703:4;-1:-1:-1;;;;;;37727:47:0;;-1:-1:-1;;;37727:47:0;;:87;;-1:-1:-1;;;;;;;;;;12599:40:0;;;37778:36;37720:94;37618:204;-1:-1:-1;;37618:204:0:o;24276:100::-;24330:13;24363:5;24356:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24276:100;:::o;26627:201::-;26710:4;18578:10;26766:32;18578:10;26782:7;26791:6;26766:8;:32::i;:::-;-1:-1:-1;26816:4:0;;26627:201;-1:-1:-1;;;26627:201:0:o;59154:309::-;50961:33;-1:-1:-1;;;;;;;;;;;18578:10:0;37914:147;:::i;50961:33::-;50939:127;;;;-1:-1:-1;;;50939:127:0;;;;;;;:::i;:::-;;;;;;;;;51896:29:::1;-1:-1:-1::0;;;;;;;;;;;18578:10:0;37914:147;:::i;51896:29::-:1;51895:30;51873:131;;;;-1:-1:-1::0;;;51873:131:0::1;;;;;;;:::i;:::-;59293:52:::2;18578:10:::0;59329:7:::2;59338:6;59293:21;:52::i;:::-;59356:45;18578:10:::0;59385:7:::2;59394:6;59356:14;:45::i;:::-;59417:38;::::0;;18578:10;7552:34:1;;-1:-1:-1;;;;;7622:15:1;;7617:2;7602:18;;7595:43;7654:18;;;7647:34;;;59417:38:0::2;::::0;7502:2:1;7487:18;59417:38:0::2;;;;;;;59154:309:::0;;:::o;57520:533::-;48176:14;;-1:-1:-1;;;;;48176:14:0;18578:10;48268:31;;:58;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;48303:23:0;18578:10;-1:-1:-1;;;;;48303:23:0;;48268:58;48246:155;;;;-1:-1:-1;;;48246:155:0;;;;;;;:::i;:::-;43782:4;43806:7;;;44060:9:::1;44052:38;;;;-1:-1:-1::0;;;44052:38:0::1;;;;;;;:::i;:::-;57757:15:::2;57769:2;57757:11;:15::i;:::-;57749:71;;;::::0;-1:-1:-1;;;57749:71:0;;17626:2:1;57749:71:0::2;::::0;::::2;17608:21:1::0;17665:2;17645:18;;;17638:30;17704:34;17684:18;;;17677:62;-1:-1:-1;;;17755:18:1;;;17748:41;17806:19;;57749:71:0::2;17424:407:1::0;57749:71:0::2;57840:12;57849:2;57840:8;:12::i;:::-;57839:13;57831:54;;;::::0;-1:-1:-1;;;57831:54:0;;24353:2:1;57831:54:0::2;::::0;::::2;24335:21:1::0;24392:2;24372:18;;;24365:30;24431;24411:18;;;24404:58;24479:18;;57831:54:0::2;24151:352:1::0;57831:54:0::2;57902:14;::::0;57896:29:::2;::::0;-1:-1:-1;;;;;57902:14:0::2;57918:6:::0;57896:5:::2;:29::i;:::-;57952:14;::::0;57936:43:::2;::::0;-1:-1:-1;;;;;57952:14:0::2;57968:2:::0;57972:6;57936:15:::2;:43::i;:::-;57995:50;58016:4;58022:10;58034:2;58038:6;57995:50;;;;;;;;;:::i;:::-;;;;;;;;57520:533:::0;;;;:::o;20598:245::-;-1:-1:-1;;;;;20780:26:0;;20753:7;20780:26;;;:19;:26;;;;;;:38;;;;20807:10;;20780:38;:::i;:::-;;;;;;;;;;;;;20819:15;20780:55;;;;;;:::i;:::-;;;;;;;;;;;;;;20773:62;;20598:245;;;;;:::o;51458:367::-;48960:18;;-1:-1:-1;;;;;48960:18:0;18578:10;49060:35;;:62;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;49099:23:0;18578:10;-1:-1:-1;;;;;49099:23:0;;49060:62;49038:163;;;;-1:-1:-1;;;49038:163:0;;;;;;;:::i;:::-;51562:25:::1;51579:7;51562:16;:25::i;:::-;51561:26;51539:119;;;::::0;-1:-1:-1;;;51539:119:0;;18444:2:1;51539:119:0::1;::::0;::::1;18426:21:1::0;18483:2;18463:18;;;18456:30;18522:34;18502:18;;;18495:62;-1:-1:-1;;;18573:18:1;;;18566:41;18624:19;;51539:119:0::1;18242:407:1::0;51539:119:0::1;-1:-1:-1::0;;;;;51677:21:0;::::1;51669:67;;;::::0;-1:-1:-1;;;51669:67:0;;14581:2:1;51669:67:0::1;::::0;::::1;14563:21:1::0;14620:2;14600:18;;;14593:30;14659:34;14639:18;;;14632:62;-1:-1:-1;;;14710:18:1;;;14703:31;14751:19;;51669:67:0::1;14379:397:1::0;51669:67:0::1;51747:31;-1:-1:-1::0;;;;;;;;;;;51770:7:0::1;51747:10;:31::i;:::-;51794:23;::::0;-1:-1:-1;;;;;7268:32:1;;7250:51;;51794:23:0::1;::::0;7238:2:1;7223:18;51794:23:0::1;;;;;;;;51458:367:::0;:::o;58743:377::-;58896:4;50961:33;-1:-1:-1;;;;;;;;;;;18578:10:0;37914:147;:::i;50961:33::-;50939:127;;;;-1:-1:-1;;;50939:127:0;;;;;;;:::i;:::-;51896:29:::1;-1:-1:-1::0;;;;;;;;;;;18578:10:0;37914:147;:::i;51896:29::-:1;51895:30;51873:131;;;;-1:-1:-1::0;;;51873:131:0::1;;;;;;;:::i;:::-;58912:16:::2;58931:36;58950:4;58956:2;58960:6;58931:18;:36::i;:::-;58912:55;;58998:2;-1:-1:-1::0;;;;;58983:26:0::2;58992:4;-1:-1:-1::0;;;;;58983:26:0::2;-1:-1:-1::0;;;;;;;;;;;59002:6:0::2;58983:26;;;;8863:25:1::0;;8851:2;8836:18;;8717:177;58983:26:0::2;;;;;;;;59025:58;59033:4:::0;18578:10;59053:29:::2;59063:4:::0;18578:10;26156:151;:::i;59053:29::-:2;59025:58;::::0;;-1:-1:-1;;;;;7570:15:1;;;7552:34;;7622:15;;;;7617:2;7602:18;;7595:43;7654:18;;;7647:34;7502:2;7487:18;59025:58:0::2;;;;;;;59101:11:::0;58743:377;-1:-1:-1;;;;58743:377:0:o;39438:147::-;39119:7;39146:12;;;:6;:12;;;;;:22;;;37496:30;37507:4;18578:10;37496;:30::i;:::-;39552:25:::1;39563:4;39569:7;39552:10;:25::i;:::-;39438:147:::0;;;:::o;40486:218::-;-1:-1:-1;;;;;40582:23:0;;18578:10;40582:23;40574:83;;;;-1:-1:-1;;;40574:83:0;;24710:2:1;40574:83:0;;;24692:21:1;24749:2;24729:18;;;24722:30;24788:34;24768:18;;;24761:62;-1:-1:-1;;;24839:18:1;;;24832:45;24894:19;;40574:83:0;24508:411:1;40574:83:0;40670:26;40682:4;40688:7;40670:11;:26::i;:::-;40486:218;;:::o;59498:412::-;59665:4;50961:33;-1:-1:-1;;;;;;;;;;;18578:10:0;37914:147;:::i;50961:33::-;50939:127;;;;-1:-1:-1;;;50939:127:0;;;;;;;:::i;:::-;51896:29:::1;-1:-1:-1::0;;;;;;;;;;;18578:10:0;37914:147;:::i;51896:29::-:1;51895:30;51873:131;;;;-1:-1:-1::0;;;51873:131:0::1;;;;;;;:::i;:::-;59687:20:::2;59710:44;59747:6:::0;59710:32:::2;18578:10:::0;59734:7:::2;59710:9;:32::i;:::-;:36:::0;::::2;:44::i;:::-;59687:67:::0;-1:-1:-1;59765:45:0::2;18578:10:::0;59774:12:::2;59788:7;59797:12;59765:8;:45::i;:::-;59826:54;18578:10:::0;59844:12:::2;59826:54;::::0;;-1:-1:-1;;;;;7570:15:1;;;7552:34;;7622:15;;;7617:2;7602:18;;7595:43;7654:18;;7647:34;;;7502:2;7487:18;59826:54:0::2;;;;;;;-1:-1:-1::0;59898:4:0::2;::::0;59498:412;-1:-1:-1;;;59498:412:0:o;53104:114::-;48960:18;;-1:-1:-1;;;;;48960:18:0;18578:10;49060:35;;:62;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;49099:23:0;18578:10;-1:-1:-1;;;;;49099:23:0;;49060:62;49038:163;;;;-1:-1:-1;;;49038:163:0;;;;;;;:::i;:::-;53163:10:::1;:8;:10::i;:::-;53189:21;18578:10:::0;53197:12:::1;53189:21;::::0;-1:-1:-1;;;;;7268:32:1;;;7250:51;;7238:2;7223:18;53189:21:0::1;;;;;;;;53104:114::o:0;53631:383::-;49828:19;;-1:-1:-1;;;;;49828:19:0;18578:10;49930:36;;:63;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;49970:23:0;18578:10;-1:-1:-1;;;;;49970:23:0;;49930:63;49908:165;;;;-1:-1:-1;;;49908:165:0;;18856:2:1;49908:165:0;;;18838:21:1;18895:2;18875:18;;;18868:30;18934:34;18914:18;;;18907:62;-1:-1:-1;;;18985:18:1;;;18978:50;19045:19;;49908:165:0;18654:416:1;49908:165:0;-1:-1:-1;;;;;25668:18:0;;53719:15:::1;25668:18:::0;;;:9;:18;;;;;;53788:17;;::::1;;53766:104;;;::::0;-1:-1:-1;;;53766:104:0;;18038:2:1;53766:104:0::1;::::0;::::1;18020:21:1::0;18077:2;18057:18;;;18050:30;18116:34;18096:18;;;18089:62;-1:-1:-1;;;18167:18:1;;;18160:35;18212:19;;53766:104:0::1;17836:401:1::0;53766:104:0::1;53906:14;::::0;53881:48:::1;::::0;53897:7;;-1:-1:-1;;;;;53906:14:0::1;53922:6:::0;53881:15:::1;:48::i;:::-;53946:14;::::0;53940:29:::1;::::0;-1:-1:-1;;;;;53946:14:0::1;53962:6:::0;53940:5:::1;:29::i;:::-;53985:21;::::0;;-1:-1:-1;;;;;8438:32:1;;8420:51;;8502:2;8487:18;;8480:34;;;53985:21:0::1;::::0;8393:18:1;53985:21:0::1;;;;;;;;53708:306;53631:383:::0;;:::o;54259:164::-;48176:14;;-1:-1:-1;;;;;48176:14:0;18578:10;48268:31;;:58;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;48303:23:0;18578:10;-1:-1:-1;;;;;48303:23:0;;48268:58;48246:155;;;;-1:-1:-1;;;48246:155:0;;;;;;;:::i;:::-;54331:14:::1;::::0;54325:48:::1;::::0;-1:-1:-1;;;;;54331:14:0::1;54356:16;25321:2:::0;54356::::1;:16;:::i;:::-;54347:25;::::0;:6;:25:::1;:::i;:::-;54325:5;:48::i;:::-;54389:26;18578:10:::0;54394:12:::1;54389:26;::::0;;-1:-1:-1;;;;;8438:32:1;;;8420:51;;8502:2;8487:18;;8480:34;;;8393:18;54389:26:0::1;8246:274:1::0;52594:143:0;48960:18;;-1:-1:-1;;;;;48960:18:0;18578:10;49060:35;;:62;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;49099:23:0;18578:10;-1:-1:-1;;;;;49099:23:0;;49060:62;49038:163;;;;-1:-1:-1;;;49038:163:0;;;;;;;:::i;:::-;52669:27:::1;-1:-1:-1::0;;;;;;;;;;;52688:7:0::1;52669:10;:27::i;:::-;52712:17;::::0;-1:-1:-1;;;;;7268:32:1;;7250:51;;52712:17:0::1;::::0;7238:2:1;7223:18;52712:17:0::1;7104:203:1::0;56044:638:0;50961:33;-1:-1:-1;;;;;;;;;;;18578:10:0;37914:147;:::i;50961:33::-;50939:127;;;;-1:-1:-1;;;50939:127:0;;;;;;;:::i;:::-;51896:29:::1;-1:-1:-1::0;;;;;;;;;;;18578:10:0;37914:147;:::i;51896:29::-:1;51895:30;51873:131;;;;-1:-1:-1::0;;;51873:131:0::1;;;;;;;:::i;:::-;43782:4:::0;43806:7;;;44060:9:::2;44052:38;;;;-1:-1:-1::0;;;44052:38:0::2;;;;;;;:::i;:::-;56360:23:::3;18578:10:::0;56370:12:::3;18498:98:::0;56360:23:::3;56350:6;:33;;56328:116;;;::::0;-1:-1:-1;;;56328:116:0;;22421:2:1;56328:116:0::3;::::0;::::3;22403:21:1::0;22460:2;22440:18;;;22433:30;22499:34;22479:18;;;22472:62;-1:-1:-1;;;22550:18:1;;;22543:31;22591:19;;56328:116:0::3;22219:397:1::0;56328:116:0::3;56455:66;56485:10;56497:15;56514:6;56455:29;:66::i;:::-;56537:137;18578:10:::0;56602::::3;56627:15;56657:6;56537:137;;;;;;;;;:::i;53250:360::-:0;19564:14;;-1:-1:-1;;;;;19564:14:0;18578:10;-1:-1:-1;;;;;19548:30:0;;19526:127;;;;-1:-1:-1;;;19526:127:0;;;;;;;:::i;:::-;53330:17:::1;19191:6:::0;;;;-1:-1:-1;;;;;19191:6:0;53368:22:::1;:20;:22::i;:::-;53425:44;37050:4;18578:10:::0;53425::::1;:44::i;:::-;53480:35;-1:-1:-1::0;;;;;;;;;;;18578:10:0;39438:147;:::i;53480:35::-:1;53526:32;-1:-1:-1::0;;;;;;;;;;;18578:10:0;39830:149;:::i;53526:32::-:1;53569:33;-1:-1:-1::0;;;;;;;;;;;53592:9:0::1;53569:10;:33::i;:::-;53319:291;53250:360::o:0;48429:446::-;19370:6;;-1:-1:-1;;;;;19370:6:0;;;;;18578:10;19370:22;19348:110;;;;-1:-1:-1;;;19348:110:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;48534:30:0;::::1;48512:116;;;::::0;-1:-1:-1;;;48512:116:0;;19277:2:1;48512:116:0::1;::::0;::::1;19259:21:1::0;19316:2;19296:18;;;19289:30;19355:34;19335:18;;;19328:62;-1:-1:-1;;;19406:18:1;;;19399:34;19450:19;;48512:116:0::1;19075:400:1::0;48512:116:0::1;48662:14;::::0;48639:38:::1;::::0;-1:-1:-1;;;;;;;;;;;45460:23:0;-1:-1:-1;;;;;48662:14:0::1;48639:10;:38::i;:::-;48688:14;:33:::0;;-1:-1:-1;;;;;;48688:33:0::1;-1:-1:-1::0;;;;;48688:33:0;::::1;::::0;;::::1;::::0;;;48732:37:::1;::::0;-1:-1:-1;;;;;;;;;;;45460:23:0;48732:9:::1;:37::i;:::-;48799:14;::::0;48780:34:::1;::::0;-1:-1:-1;;;;;;;;;;;45524:19:0;-1:-1:-1;;;;;48799:14:0::1;48780:10;:34::i;:::-;48830:37;::::0;-1:-1:-1;;;;;7268:32:1;;7250:51;;48830:37:0::1;::::0;7238:2:1;7223:18;48830:37:0::1;7104:203:1::0;50101:523:0;19370:6;;-1:-1:-1;;;;;19370:6:0;;;;;18578:10;19370:22;19348:110;;;;-1:-1:-1;;;19348:110:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;50239:35:0;::::1;50217:125;;;::::0;-1:-1:-1;;;50217:125:0;;22012:2:1;50217:125:0::1;::::0;::::1;21994:21:1::0;22051:2;22031:18;;;22024:30;22090:34;22070:18;;;22063:62;-1:-1:-1;;;22141:18:1;;;22134:38;22189:19;;50217:125:0::1;21810:404:1::0;50217:125:0::1;50376:19;::::0;50353:43:::1;::::0;-1:-1:-1;;;;;;;;;;;45460:23:0;-1:-1:-1;;;;;50376:19:0::1;50353:10;:43::i;:::-;50407:19;:43:::0;;-1:-1:-1;;;;;;50407:43:0::1;-1:-1:-1::0;;;;;50407:43:0;::::1;::::0;;::::1;::::0;;;50461:42:::1;::::0;-1:-1:-1;;;;;;;;;;;45460:23:0;50461:9:::1;:42::i;:::-;50533:19;::::0;50514:39:::1;::::0;-1:-1:-1;;;;;;;;;;;45524:19:0;-1:-1:-1;;;;;50533:19:0::1;50514:10;:39::i;:::-;50569:47;::::0;-1:-1:-1;;;;;7268:32:1;;7250:51;;50569:47:0::1;::::0;7238:2:1;7223:18;50569:47:0::1;7104:203:1::0;56690:822:0;48176:14;;-1:-1:-1;;;;;48176:14:0;18578:10;48268:31;;:58;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;48303:23:0;18578:10;-1:-1:-1;;;;;48303:23:0;;48268:58;48246:155;;;;-1:-1:-1;;;48246:155:0;;;;;;;:::i;:::-;43782:4;43806:7;;;44060:9:::1;44052:38;;;;-1:-1:-1::0;;;44052:38:0::1;;;;;;;:::i;:::-;56923:17:::2;56935:4;56923:11;:17::i;:::-;56915:71;;;;-1:-1:-1::0;;;56915:71:0::2;;;;;;;:::i;:::-;57006:14;57015:4;57006:8;:14::i;:::-;57005:15;56997:54;;;::::0;-1:-1:-1;;;56997:54:0;;19682:2:1;56997:54:0::2;::::0;::::2;19664:21:1::0;19721:2;19701:18;;;19694:30;19760:28;19740:18;;;19733:56;19806:18;;56997:54:0::2;19480:350:1::0;56997:54:0::2;57062:19;57084:41;57104:4;57110:10;57122:2;57084:19;:41::i;:::-;57062:63;;57154:11;57144:6;:21;;57136:64;;;::::0;-1:-1:-1;;;57136:64:0;;23994:2:1;57136:64:0::2;::::0;::::2;23976:21:1::0;24033:2;24013:18;;;24006:30;24072:32;24052:18;;;24045:60;24122:18;;57136:64:0::2;23792:354:1::0;57136:64:0::2;57233:14;::::0;57211:45:::2;::::0;57227:4;;-1:-1:-1;;;;;57233:14:0::2;57249:6:::0;57211:15:::2;:45::i;:::-;57273:14;::::0;57267:29:::2;::::0;-1:-1:-1;;;;;57273:14:0::2;57289:6:::0;57267:5:::2;:29::i;:::-;57307:135;57347:4:::0;57366:10;57391:2;57408:23:::2;:11:::0;57424:6;57408:15:::2;:23::i;:::-;57307:25;:135::i;:::-;57458:46;57475:4;57481:10;57493:2;57497:6;57458:46;;;;;;;;;:::i;:::-;;;;;;;;56904:608;56690:822:::0;;;;:::o;52963:108::-;48960:18;;-1:-1:-1;;;;;48960:18:0;18578:10;49060:35;;:62;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;49099:23:0;18578:10;-1:-1:-1;;;;;49099:23:0;;49060:62;49038:163;;;;-1:-1:-1;;;49038:163:0;;;;;;;:::i;:::-;53020:8:::1;:6;:8::i;:::-;53044:19;18578:10:::0;53050:12:::1;18498:98:::0;52217:332;48960:18;;-1:-1:-1;;;;;48960:18:0;18578:10;49060:35;;:62;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;49099:23:0;18578:10;-1:-1:-1;;;;;49099:23:0;;49060:62;49038:163;;;;-1:-1:-1;;;49038:163:0;;;;;;;:::i;:::-;52313:25:::1;52330:7;52313:16;:25::i;:::-;52312:26;52290:112;;;::::0;-1:-1:-1;;;52290:112:0;;23589:2:1;52290:112:0::1;::::0;::::1;23571:21:1::0;23628:2;23608:18;;;23601:30;23667:34;23647:18;;;23640:62;-1:-1:-1;;;23718:18:1;;;23711:34;23762:19;;52290:112:0::1;23387:400:1::0;52290:112:0::1;-1:-1:-1::0;;;;;52421:21:0;::::1;52413:60;;;::::0;-1:-1:-1;;;52413:60:0;;21657:2:1;52413:60:0::1;::::0;::::1;21639:21:1::0;21696:2;21676:18;;;21669:30;21735:28;21715:18;;;21708:56;21781:18;;52413:60:0::1;21455:350:1::0;52413:60:0::1;52484:26;-1:-1:-1::0;;;;;;;;;;;52502:7:0::1;52484:9;:26::i;:::-;52526:15;::::0;-1:-1:-1;;;;;7268:32:1;;7250:51;;52526:15:0::1;::::0;7238:2:1;7223:18;52526:15:0::1;7104:203:1::0;37914:147:0;38000:4;38024:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;38024:29:0;;;;;;;;;;;;;;;37914:147::o;24495:104::-;24551:13;24584:7;24577:14;;;;;:::i;54072:166::-;48176:14;;-1:-1:-1;;;;;48176:14:0;18578:10;48268:31;;:58;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;48303:23:0;18578:10;-1:-1:-1;;;;;48303:23:0;;48268:58;48246:155;;;;-1:-1:-1;;;48246:155:0;;;;;;;:::i;:::-;54138:49:::1;54144:15;48176:14:::0;;-1:-1:-1;;;;;48176:14:0;;48103:95;54144:15:::1;54170:16;25321:2:::0;54170::::1;:16;:::i;:::-;54161:25;::::0;:6;:25:::1;:::i;:::-;54138:5;:49::i;:::-;54203:27;18578:10:::0;54208:12:::1;18498:98:::0;59945:483;60112:4;50961:33;-1:-1:-1;;;;;;;;;;;18578:10:0;37914:147;:::i;50961:33::-;50939:127;;;;-1:-1:-1;;;50939:127:0;;;;;;;:::i;:::-;51896:29:::1;-1:-1:-1::0;;;;;;;;;;;18578:10:0;37914:147;:::i;51896:29::-:1;51895:30;51873:131;;;;-1:-1:-1::0;;;51873:131:0::1;;;;;;;:::i;:::-;60134:20:::2;60157:115;60208:6;60157:115;;;;;;;;;;;;;;;;::::0;:32:::2;60167:12;18578:10:::0;;18498:98;60167:12:::2;60181:7;60157:9;:32::i;:::-;:36:::0;:115;:36:::2;:115::i;:::-;60134:138:::0;-1:-1:-1;60283:45:0::2;18578:10:::0;60292:12:::2;18498:98:::0;60283:45:::2;60344:54;18578:10:::0;60362:12:::2;18498:98:::0;55708:217;55786:4;55803:41;18578:10;55833:2;55837:6;55803:15;:41::i;:::-;55860:34;;8863:25:1;;;-1:-1:-1;;;;;55860:34:0;;;18578:10;;-1:-1:-1;;;;;;;;;;;55860:34:0;8851:2:1;8836:18;55860:34:0;;;;;;;-1:-1:-1;55913:4:0;55708:217;;;;:::o;51094:119::-;51153:4;51177:28;-1:-1:-1;;;;;;;;;;;51197:7:0;51177;:28::i;19787:223::-;19370:6;;-1:-1:-1;;;;;19370:6:0;;;;;18578:10;19370:22;19348:110;;;;-1:-1:-1;;;19348:110:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;19863:22:0;::::1;19855:67;;;::::0;-1:-1:-1;;;19855:67:0;;22823:2:1;19855:67:0::1;::::0;::::1;22805:21:1::0;;;22842:18;;;22835:30;22901:34;22881:18;;;22874:62;22953:18;;19855:67:0::1;22621:356:1::0;19855:67:0::1;19933:14;:25:::0;;-1:-1:-1;;;;;;19933:25:0::1;-1:-1:-1::0;;;;;19933:25:0;::::1;::::0;;::::1;::::0;;;19974:28:::1;::::0;::::1;::::0;-1:-1:-1;;19974:28:0::1;19787:223:::0;:::o;39830:149::-;39119:7;39146:12;;;:6;:12;;;;;:22;;;37496:30;37507:4;18578:10;37496;:30::i;:::-;39945:26:::1;39957:4;39963:7;39945:11;:26::i;49229:513::-:0;19370:6;;-1:-1:-1;;;;;19370:6:0;;;;;18578:10;19370:22;19348:110;;;;-1:-1:-1;;;19348:110:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;49365:34:0;::::1;49343:124;;;::::0;-1:-1:-1;;;49343:124:0;;10644:2:1;49343:124:0::1;::::0;::::1;10626:21:1::0;10683:2;10663:18;;;10656:30;10722:34;10702:18;;;10695:62;-1:-1:-1;;;10773:18:1;;;10766:38;10821:19;;49343:124:0::1;10442:404:1::0;49343:124:0::1;49501:18;::::0;49478:42:::1;::::0;-1:-1:-1;;;;;;;;;;;45460:23:0;-1:-1:-1;;;;;49501:18:0::1;49478:10;:42::i;:::-;49531:18;:41:::0;;-1:-1:-1;;;;;;49531:41:0::1;-1:-1:-1::0;;;;;49531:41:0;::::1;::::0;;::::1;::::0;;;49583::::1;::::0;-1:-1:-1;;;;;;;;;;;45460:23:0;49583:9:::1;:41::i;:::-;49654:18;::::0;49635:38:::1;::::0;-1:-1:-1;;;;;;;;;;;45524:19:0;-1:-1:-1;;;;;49654:18:0::1;49635:10;:38::i;:::-;49689:45;::::0;-1:-1:-1;;;;;7268:32:1;;7250:51;;49689:45:0::1;::::0;7238:2:1;7223:18;49689:45:0::1;7104:203:1::0;26156:151:0;-1:-1:-1;;;;;26272:18:0;;;26245:7;26272:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;26156:151::o;51242:154::-;48960:18;;-1:-1:-1;;;;;48960:18:0;18578:10;49060:35;;:62;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;49099:23:0;18578:10;-1:-1:-1;;;;;49099:23:0;;49060:62;49038:163;;;;-1:-1:-1;;;49038:163:0;;;;;;;:::i;:::-;51321:30:::1;-1:-1:-1::0;;;;;;;;;;;51343:7:0::1;51321:9;:30::i;:::-;51367:21;::::0;-1:-1:-1;;;;;7268:32:1;;7250:51;;51367:21:0::1;::::0;7238:2:1;7223:18;51367:21:0::1;7104:203:1::0;52032:112:0;52088:4;52112:24;-1:-1:-1;;;;;;;;;;;52128:7:0;52112;:24::i;50632:265::-;50696:4;50744:15;48176:14;;-1:-1:-1;;;;;48176:14:0;;48103:95;50744:15;-1:-1:-1;;;;;50733:26:0;:7;-1:-1:-1;;;;;50733:26:0;;:73;;;-1:-1:-1;48960:18:0;;-1:-1:-1;;;;;50776:30:0;;;48960:18;;50776:30;50733:73;:121;;;-1:-1:-1;49828:19:0;;-1:-1:-1;;;;;50823:31:0;;;49828:19;;50823:31;50733:121;:156;;;-1:-1:-1;19164:7:0;19191:6;;;;-1:-1:-1;;;;;19191:6:0;-1:-1:-1;;;;;50871:18:0;:7;-1:-1:-1;;;;;50871:18:0;;50713:176;50632:265;-1:-1:-1;;50632:265:0:o;52790:142::-;52858:4;52882:20;52894:7;52882:11;:20::i;:::-;:42;;;;;52907:17;52916:7;52907:8;:17::i;:::-;52906:18;52875:49;52790:142;-1:-1:-1;;52790:142:0:o;14320:451::-;14395:13;14421:19;14453:10;14457:6;14453:1;:10;:::i;:::-;:14;;14466:1;14453:14;:::i;:::-;14443:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14443:25:0;;14421:47;;-1:-1:-1;;;14479:6:0;14486:1;14479:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;14479:15:0;;;;;;;;;-1:-1:-1;;;14505:6:0;14512:1;14505:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;14505:15:0;;;;;;;;-1:-1:-1;14536:9:0;14548:10;14552:6;14548:1;:10;:::i;:::-;:14;;14561:1;14548:14;:::i;:::-;14536:26;;14531:135;14568:1;14564;:5;14531:135;;;-1:-1:-1;;;14616:5:0;14624:3;14616:11;14603:25;;;;;;;:::i;:::-;;;;14591:6;14598:1;14591:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;14591:37:0;;;;;;;;-1:-1:-1;14653:1:0;14643:11;;;;;14571:3;;;:::i;:::-;;;14531:135;;;-1:-1:-1;14684:10:0;;14676:55;;;;-1:-1:-1;;;14676:55:0;;9879:2:1;14676:55:0;;;9861:21:1;;;9898:18;;;9891:30;9957:34;9937:18;;;9930:62;10009:18;;14676:55:0;9677:356:1;14676:55:0;14756:6;14320:451;-1:-1:-1;;;14320:451:0:o;32447:380::-;-1:-1:-1;;;;;32583:19:0;;32575:68;;;;-1:-1:-1;;;32575:68:0;;23184:2:1;32575:68:0;;;23166:21:1;23223:2;23203:18;;;23196:30;23262:34;23242:18;;;23235:62;-1:-1:-1;;;23313:18:1;;;23306:34;23357:19;;32575:68:0;22982:400:1;32575:68:0;-1:-1:-1;;;;;32662:21:0;;32654:68;;;;-1:-1:-1;;;32654:68:0;;13048:2:1;32654:68:0;;;13030:21:1;13087:2;13067:18;;;13060:30;13126:34;13106:18;;;13099:62;-1:-1:-1;;;13177:18:1;;;13170:32;13219:19;;32654:68:0;12846:398:1;32654:68:0;-1:-1:-1;;;;;32735:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;32787:32;;8863:25:1;;;32787:32:0;;8836:18:1;32787:32:0;;;;;;;32447:380;;;:::o;58142:550::-;50961:33;-1:-1:-1;;;;;;;;;;;18578:10:0;37914:147;:::i;50961:33::-;50939:127;;;;-1:-1:-1;;;50939:127:0;;;;;;;:::i;:::-;51896:29:::1;-1:-1:-1::0;;;;;;;;;;;18578:10:0;37914:147;:::i;51896:29::-:1;51895:30;51873:131;;;;-1:-1:-1::0;;;51873:131:0::1;;;;;;;:::i;:::-;43782:4:::0;43806:7;;;44060:9:::2;44052:38;;;;-1:-1:-1::0;;;44052:38:0::2;;;;;;;:::i;:::-;58333:20:::3;58345:7;58333:11;:20::i;:::-;58325:74;;;;-1:-1:-1::0;;;58325:74:0::3;;;;;;;:::i;:::-;58418:19;58430:6;58418:11;:19::i;:::-;58410:72;;;::::0;-1:-1:-1;;;58410:72:0;;15390:2:1;58410:72:0::3;::::0;::::3;15372:21:1::0;15429:2;15409:18;;;15402:30;15468:34;15448:18;;;15441:62;-1:-1:-1;;;15519:18:1;;;15512:38;15567:19;;58410:72:0::3;15188:404:1::0;58410:72:0::3;58502:17;58511:7;58502:8;:17::i;:::-;58501:18;58493:57;;;::::0;-1:-1:-1;;;58493:57:0;;19682:2:1;58493:57:0::3;::::0;::::3;19664:21:1::0;19721:2;19701:18;;;19694:30;19760:28;19740:18;;;19733:56;19806:18;;58493:57:0::3;19480:350:1::0;58493:57:0::3;58570:16;58579:6;58570:8;:16::i;:::-;58569:17;58561:55;;;::::0;-1:-1:-1;;;58561:55:0;;17272:2:1;58561:55:0::3;::::0;::::3;17254:21:1::0;17311:2;17291:18;;;17284:30;-1:-1:-1;;;17330:18:1;;;17323:55;17395:18;;58561:55:0::3;17070:349:1::0;30686:399:0;-1:-1:-1;;;;;30770:21:0;;30762:65;;;;-1:-1:-1;;;30762:65:0;;25546:2:1;30762:65:0;;;25528:21:1;25585:2;25565:18;;;25558:30;25624:33;25604:18;;;25597:61;25675:18;;30762:65:0;25344:355:1;30762:65:0;30840:49;30869:1;30873:7;30882:6;30840:20;:49::i;:::-;30918:6;30902:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;30935:18:0;;;;;;:9;:18;;;;;:28;;30957:6;;30935:18;:28;;30957:6;;30935:28;:::i;:::-;;;;-1:-1:-1;;30979:37:0;;8863:25:1;;;-1:-1:-1;;;;;30979:37:0;;;30996:1;;-1:-1:-1;;;;;;;;;;;30979:37:0;8851:2:1;8836:18;30979:37:0;;;;;;;40486:218;;:::o;29772:627::-;-1:-1:-1;;;;;29903:18:0;;29895:68;;;;-1:-1:-1;;;29895:68:0;;20849:2:1;29895:68:0;;;20831:21:1;20888:2;20868:18;;;20861:30;20927:34;20907:18;;;20900:62;-1:-1:-1;;;20978:18:1;;;20971:35;21023:19;;29895:68:0;20647:401:1;29895:68:0;-1:-1:-1;;;;;29982:16:0;;29974:64;;;;-1:-1:-1;;;29974:64:0;;10240:2:1;29974:64:0;;;10222:21:1;10279:2;10259:18;;;10252:30;10318:34;10298:18;;;10291:62;-1:-1:-1;;;10369:18:1;;;10362:33;10412:19;;29974:64:0;10038:399:1;29974:64:0;30051:38;30072:4;30078:2;30082:6;30051:20;:38::i;:::-;-1:-1:-1;;;;;30124:15:0;;30102:19;30124:15;;;:9;:15;;;;;;30158:21;;;;30150:72;;;;-1:-1:-1;;;30150:72:0;;14983:2:1;30150:72:0;;;14965:21:1;15022:2;15002:18;;;14995:30;15061:34;15041:18;;;15034:62;-1:-1:-1;;;15112:18:1;;;15105:36;15158:19;;30150:72:0;14781:402:1;30150:72:0;-1:-1:-1;;;;;30258:15:0;;;;;;;:9;:15;;;;;;30276:20;;;30258:38;;30318:13;;;;;;;;:23;;30290:6;;30258:15;30318:23;;30290:6;;30318:23;:::i;:::-;;;;-1:-1:-1;30354:37:0;;-1:-1:-1;39438:147:0;30354:37;29884:515;29772:627;;;:::o;27408:295::-;27539:4;18578:10;27597:38;27613:4;18578:10;27628:6;27597:15;:38::i;:::-;27646:27;27656:4;27662:2;27666:6;27646:9;:27::i;:::-;-1:-1:-1;27691:4:0;;27408:295;-1:-1:-1;;;;27408:295:0:o;38351:505::-;38440:22;38448:4;38454:7;38440;:22::i;:::-;38435:414;;38628:41;38656:7;-1:-1:-1;;;;;38628:41:0;38666:2;38628:19;:41::i;:::-;38742:38;38770:4;38777:2;38742:19;:38::i;:::-;38533:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;38533:270:0;;;;;;;;;;-1:-1:-1;;;38479:358:0;;;;;;;:::i;41987:238::-;42071:22;42079:4;42085:7;42071;:22::i;:::-;42066:152;;42110:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;42110:29:0;;;;;;;;;:36;;-1:-1:-1;;42110:36:0;42142:4;42110:36;;;42193:12;18578:10;;18498:98;42193:12;-1:-1:-1;;;;;42166:40:0;42184:7;-1:-1:-1;;;;;42166:40:0;42178:4;42166:40;;;;;;;;;;41987:238;;:::o;42357:239::-;42441:22;42449:4;42455:7;42441;:22::i;:::-;42437:152;;;42512:5;42480:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;42480:29:0;;;;;;;;;;:37;;-1:-1:-1;;42480:37:0;;;42537:40;18578:10;;42480:12;;42537:40;;42512:5;42537:40;42357:239;;:::o;2929:98::-;2987:7;3014:5;3018:1;3014;:5;:::i;44794:120::-;43782:4;43806:7;;;44330:41;;;;-1:-1:-1;;;44330:41:0;;11473:2:1;44330:41:0;;;11455:21:1;11512:2;11492:18;;;11485:30;-1:-1:-1;;;11531:18:1;;;11524:50;11591:18;;44330:41:0;11271:344:1;44330:41:0;44863:5:::1;44853:15:::0;;-1:-1:-1;;44853:15:0::1;::::0;;44884:22:::1;18578:10:::0;44893:12:::1;18498:98:::0;31418:591;-1:-1:-1;;;;;31502:21:0;;31494:67;;;;-1:-1:-1;;;31494:67:0;;20037:2:1;31494:67:0;;;20019:21:1;20076:2;20056:18;;;20049:30;20115:34;20095:18;;;20088:62;-1:-1:-1;;;20166:18:1;;;20159:31;20207:19;;31494:67:0;19835:397:1;31494:67:0;31574:49;31595:7;31612:1;31616:6;31574:20;:49::i;:::-;-1:-1:-1;;;;;31661:18:0;;31636:22;31661:18;;;:9;:18;;;;;;31698:24;;;;31690:71;;;;-1:-1:-1;;;31690:71:0;;11822:2:1;31690:71:0;;;11804:21:1;11861:2;11841:18;;;11834:30;11900:34;11880:18;;;11873:62;-1:-1:-1;;;11951:18:1;;;11944:32;11993:19;;31690:71:0;11620:398:1;31690:71:0;-1:-1:-1;;;;;31797:18:0;;;;;;:9;:18;;;;;31818:23;;;31797:44;;31863:12;:22;;31835:6;;31797:18;31863:22;;31835:6;;31863:22;:::i;:::-;;;;-1:-1:-1;;31903:37:0;;8863:25:1;;;31929:1:0;;-1:-1:-1;;;;;31903:37:0;;;-1:-1:-1;;;;;;;;;;;31903:37:0;8851:2:1;8836:18;31903:37:0;;;;;;;39438:147;;;:::o;20900:249::-;21065:76;18578:10;21105;21117:15;21134:6;21065:25;:76::i;20018:177::-;19564:14;;-1:-1:-1;;;;;19564:14:0;18578:10;-1:-1:-1;;;;;19548:30:0;;19526:127;;;;-1:-1:-1;;;19526:127:0;;;;;;;:::i;:::-;20097:14:::1;::::0;;::::1;20088:23:::0;;-1:-1:-1;;;;;;20088:23:0::1;20097:14;-1:-1:-1::0;;;;;20097:14:0;;::::1;20088:23:::0;::::1;::::0;;;::::1;::::0;;;;-1:-1:-1;;;;;;20122:27:0;;::::1;::::0;;;20165:22:::1;::::0;20180:6;;::::1;::::0;;::::1;7250:51:1::0;;20165:22:0::1;::::0;7238:2:1;7223:18;20165:22:0::1;7104:203:1::0;41363:112:0;41442:25;41453:4;41459:7;41442:10;:25::i;3310:98::-;3368:7;3395:5;3399:1;3395;:5;:::i;21201:386::-;18578:10;21380:68;;;;-1:-1:-1;;;21380:68:0;;16156:2:1;21380:68:0;;;16138:21:1;16195:2;16175:18;;;16168:30;16234:31;16214:18;;;16207:59;16283:18;;21380:68:0;15954:353:1;21380:68:0;-1:-1:-1;;;;;21467:18:0;;21459:59;;;;-1:-1:-1;;;21459:59:0;;15799:2:1;21459:59:0;;;15781:21:1;15838:2;15818:18;;;15811:30;15877;15857:18;;;15850:58;15925:18;;21459:59:0;15597:352:1;21459:59:0;-1:-1:-1;;;;;21529:25:0;;;;;;:19;:25;;;;;;;:37;;21573:6;;21529:25;:37;;21555:10;;21529:37;:::i;:::-;;;;;;;;;;;;;21567:2;21529:41;;;;;;:::i;:::-;;;;;;;;;;;;;;:50;-1:-1:-1;;;;21201:386:0:o;44535:118::-;43782:4;43806:7;;;44060:9;44052:38;;;;-1:-1:-1;;;44052:38:0;;;;;;;:::i;:::-;44595:7:::1;:14:::0;;-1:-1:-1;;44595:14:0::1;44605:4;44595:14;::::0;;44625:20:::1;44632:12;18578:10:::0;;18498:98;5208:240;5328:7;5389:12;5381:6;;;;5373:29;;;;-1:-1:-1;;;5373:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;5424:5:0;;;5208:240::o;54473:1227::-;51896:29;-1:-1:-1;;;;;;;;;;;18578:10:0;37914:147;:::i;51896:29::-;51895:30;51873:131;;;;-1:-1:-1;;;51873:131:0;;;;;;;:::i;:::-;43782:4;43806:7;;;44060:9:::1;44052:38;;;;-1:-1:-1::0;;;44052:38:0::1;;;;;;;:::i;:::-;48176:14:::0;;-1:-1:-1;;;;;54651:23:0;;::::2;48176:14:::0;;54651:23:::2;:43:::0;::::2;;;-1:-1:-1::0;;;;;;54678:16:0;::::2;::::0;54651:43:::2;54647:172;;;39438:147:::0;;;:::o;54647:172::-:2;48176:14:::0;;-1:-1:-1;;;;;54835:21:0;;::::2;48176:14:::0;;54835:21:::2;:43:::0;::::2;;;-1:-1:-1::0;;;;;;54860:18:0;::::2;::::0;54835:43:::2;54831:172;;;39438:147:::0;;;:::o;54831:172::-:2;48176:14:::0;;-1:-1:-1;;;;;55033:21:0;;::::2;48176:14:::0;;55033:21:::2;:59:::0;::::2;;;;55071:21;-1:-1:-1::0;;;;;;;;;;;55087:4:0::2;55071:7;:21::i;:::-;55033:101;;;;-1:-1:-1::0;;;;;;25668:18:0;;25641:7;25668:18;;;:9;:18;;;;;;55109:6:::2;:25;55033:101;55015:262;;;39438:147:::0;;;:::o;55015:262::-:2;55496:14;55505:4;55496:8;:14::i;:::-;55495:15;55487:53;;;::::0;-1:-1:-1;;;55487:53:0;;17272:2:1;55487:53:0::2;::::0;::::2;17254:21:1::0;17311:2;17291:18;;;17284:30;-1:-1:-1;;;17330:18:1;;;17323:55;17395:18;;55487:53:0::2;17070:349:1::0;55487:53:0::2;55560:12;55569:2;55560:8;:12::i;:::-;55559:13;55551:53;;;::::0;-1:-1:-1;;;55551:53:0;;13451:2:1;55551:53:0::2;::::0;::::2;13433:21:1::0;13490:2;13470:18;;;13463:30;13529:29;13509:18;;;13502:57;13576:18;;55551:53:0::2;13249:351:1::0;33114:453:0;33249:24;33276:25;33286:5;33293:7;33276:9;:25::i;:::-;33249:52;;-1:-1:-1;;33316:16:0;:37;33312:248;;33398:6;33378:16;:26;;33370:68;;;;-1:-1:-1;;;33370:68:0;;14223:2:1;33370:68:0;;;14205:21:1;14262:2;14242:18;;;14235:30;14301:31;14281:18;;;14274:59;14350:18;;33370:68:0;14021:353:1;33370:68:0;33482:51;33491:5;33498:7;33526:6;33507:16;:25;33482:8;:51::i;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:718::-;234:5;287:3;280:4;272:6;268:17;264:27;254:55;;305:1;302;295:12;254:55;341:6;328:20;367:18;404:2;400;397:10;394:36;;;410:18;;:::i;:::-;485:2;479:9;453:2;539:13;;-1:-1:-1;;535:22:1;;;559:2;531:31;527:40;515:53;;;583:18;;;603:22;;;580:46;577:72;;;629:18;;:::i;:::-;669:10;665:2;658:22;704:2;696:6;689:18;750:3;743:4;738:2;730:6;726:15;722:26;719:35;716:55;;;767:1;764;757:12;716:55;831:2;824:4;816:6;812:17;805:4;797:6;793:17;780:54;878:1;871:4;866:2;858:6;854:15;850:26;843:37;898:6;889:15;;;;;;192:718;;;;:::o;915:186::-;974:6;1027:2;1015:9;1006:7;1002:23;998:32;995:52;;;1043:1;1040;1033:12;995:52;1066:29;1085:9;1066:29;:::i;1106:260::-;1174:6;1182;1235:2;1223:9;1214:7;1210:23;1206:32;1203:52;;;1251:1;1248;1241:12;1203:52;1274:29;1293:9;1274:29;:::i;:::-;1264:39;;1322:38;1356:2;1345:9;1341:18;1322:38;:::i;:::-;1312:48;;1106:260;;;;;:::o;1371:328::-;1448:6;1456;1464;1517:2;1505:9;1496:7;1492:23;1488:32;1485:52;;;1533:1;1530;1523:12;1485:52;1556:29;1575:9;1556:29;:::i;:::-;1546:39;;1604:38;1638:2;1627:9;1623:18;1604:38;:::i;:::-;1594:48;;1689:2;1678:9;1674:18;1661:32;1651:42;;1371:328;;;;;:::o;1704:614::-;1800:6;1808;1816;1869:2;1857:9;1848:7;1844:23;1840:32;1837:52;;;1885:1;1882;1875:12;1837:52;1908:29;1927:9;1908:29;:::i;:::-;1898:39;;1988:2;1977:9;1973:18;1960:32;2011:18;2052:2;2044:6;2041:14;2038:34;;;2068:1;2065;2058:12;2038:34;2091:49;2132:7;2123:6;2112:9;2108:22;2091:49;:::i;:::-;2081:59;;2193:2;2182:9;2178:18;2165:32;2149:48;;2222:2;2212:8;2209:16;2206:36;;;2238:1;2235;2228:12;2206:36;;2261:51;2304:7;2293:8;2282:9;2278:24;2261:51;:::i;:::-;2251:61;;;1704:614;;;;;:::o;2323:683::-;2428:6;2436;2444;2452;2505:3;2493:9;2484:7;2480:23;2476:33;2473:53;;;2522:1;2519;2512:12;2473:53;2545:29;2564:9;2545:29;:::i;:::-;2535:39;;2625:2;2614:9;2610:18;2597:32;2648:18;2689:2;2681:6;2678:14;2675:34;;;2705:1;2702;2695:12;2675:34;2728:49;2769:7;2760:6;2749:9;2745:22;2728:49;:::i;:::-;2718:59;;2830:2;2819:9;2815:18;2802:32;2786:48;;2859:2;2849:8;2846:16;2843:36;;;2875:1;2872;2865:12;2843:36;;2898:51;2941:7;2930:8;2919:9;2915:24;2898:51;:::i;:::-;2323:683;;;;-1:-1:-1;2888:61:1;;2996:2;2981:18;2968:32;;-1:-1:-1;;;2323:683:1:o;3011:254::-;3079:6;3087;3140:2;3128:9;3119:7;3115:23;3111:32;3108:52;;;3156:1;3153;3146:12;3108:52;3179:29;3198:9;3179:29;:::i;:::-;3169:39;3255:2;3240:18;;;;3227:32;;-1:-1:-1;;;3011:254:1:o;3270:180::-;3329:6;3382:2;3370:9;3361:7;3357:23;3353:32;3350:52;;;3398:1;3395;3388:12;3350:52;-1:-1:-1;3421:23:1;;3270:180;-1:-1:-1;3270:180:1:o;3455:254::-;3523:6;3531;3584:2;3572:9;3563:7;3559:23;3555:32;3552:52;;;3600:1;3597;3590:12;3552:52;3636:9;3623:23;3613:33;;3665:38;3699:2;3688:9;3684:18;3665:38;:::i;3714:286::-;3772:6;3825:2;3813:9;3804:7;3800:23;3796:32;3793:52;;;3841:1;3838;3831:12;3793:52;3867:23;;-1:-1:-1;;;;;;3919:32:1;;3909:43;;3899:71;;3966:1;3963;3956:12;4005:683;4110:6;4118;4126;4134;4187:3;4175:9;4166:7;4162:23;4158:33;4155:53;;;4204:1;4201;4194:12;4155:53;4244:9;4231:23;4273:18;4314:2;4306:6;4303:14;4300:34;;;4330:1;4327;4320:12;4300:34;4353:49;4394:7;4385:6;4374:9;4370:22;4353:49;:::i;:::-;4343:59;;4455:2;4444:9;4440:18;4427:32;4411:48;;4484:2;4474:8;4471:16;4468:36;;;4500:1;4497;4490:12;4468:36;;4523:51;4566:7;4555:8;4544:9;4540:24;4523:51;:::i;:::-;4513:61;;;4593:38;4627:2;4616:9;4612:18;4593:38;:::i;:::-;4005:683;;;;-1:-1:-1;4583:48:1;;4678:2;4663:18;4650:32;;-1:-1:-1;;4005:683:1:o;4693:608::-;4789:6;4797;4805;4858:2;4846:9;4837:7;4833:23;4829:32;4826:52;;;4874:1;4871;4864:12;4826:52;4914:9;4901:23;4943:18;4984:2;4976:6;4973:14;4970:34;;;5000:1;4997;4990:12;4970:34;5023:49;5064:7;5055:6;5044:9;5040:22;5023:49;:::i;:::-;5013:59;;5125:2;5114:9;5110:18;5097:32;5081:48;;5154:2;5144:8;5141:16;5138:36;;;5170:1;5167;5160:12;5138:36;;5193:51;5236:7;5225:8;5214:9;5210:24;5193:51;:::i;:::-;5183:61;;;5291:2;5280:9;5276:18;5263:32;5253:42;;4693:608;;;;;:::o;5491:257::-;5532:3;5570:5;5564:12;5597:6;5592:3;5585:19;5613:63;5669:6;5662:4;5657:3;5653:14;5646:4;5639:5;5635:16;5613:63;:::i;:::-;5730:2;5709:15;-1:-1:-1;;5705:29:1;5696:39;;;;5737:4;5692:50;;5491:257;-1:-1:-1;;5491:257:1:o;5753:274::-;5882:3;5920:6;5914:13;5936:53;5982:6;5977:3;5970:4;5962:6;5958:17;5936:53;:::i;:::-;6005:16;;;;;5753:274;-1:-1:-1;;5753:274:1:o;6313:786::-;6724:25;6719:3;6712:38;6694:3;6779:6;6773:13;6795:62;6850:6;6845:2;6840:3;6836:12;6829:4;6821:6;6817:17;6795:62;:::i;:::-;-1:-1:-1;;;6916:2:1;6876:16;;;6908:11;;;6901:40;6966:13;;6988:63;6966:13;7037:2;7029:11;;7022:4;7010:17;;6988:63;:::i;:::-;7071:17;7090:2;7067:26;;6313:786;-1:-1:-1;;;;6313:786:1:o;7692:549::-;-1:-1:-1;;;;;7943:32:1;;7925:51;;8012:3;8007:2;7992:18;;7985:31;;;-1:-1:-1;;8039:45:1;;8064:19;;8056:6;8039:45;:::i;:::-;8132:9;8124:6;8120:22;8115:2;8104:9;8100:18;8093:50;8160:32;8185:6;8177;8160:32;:::i;:::-;8152:40;;;8228:6;8223:2;8212:9;8208:18;8201:34;7692:549;;;;;;;:::o;8899:::-;9150:3;9139:9;9132:22;9113:4;9177:45;9217:3;9206:9;9202:19;9194:6;9177:45;:::i;:::-;9270:9;9262:6;9258:22;9253:2;9242:9;9238:18;9231:50;9298:32;9323:6;9315;9298:32;:::i;:::-;-1:-1:-1;;;;;9366:32:1;;;;9361:2;9346:18;;9339:60;-1:-1:-1;;9430:2:1;9415:18;9408:34;9290:40;8899:549;-1:-1:-1;;8899:549:1:o;9453:219::-;9602:2;9591:9;9584:21;9565:4;9622:44;9662:2;9651:9;9647:18;9639:6;9622:44;:::i;10851:415::-;11053:2;11035:21;;;11092:2;11072:18;;;11065:30;11131:34;11126:2;11111:18;;11104:62;-1:-1:-1;;;11197:2:1;11182:18;;11175:49;11256:3;11241:19;;10851:415::o;12023:402::-;12225:2;12207:21;;;12264:2;12244:18;;;12237:30;12303:34;12298:2;12283:18;;12276:62;-1:-1:-1;;;12369:2:1;12354:18;;12347:36;12415:3;12400:19;;12023:402::o;12430:411::-;12632:2;12614:21;;;12671:2;12651:18;;;12644:30;12710:34;12705:2;12690:18;;12683:62;-1:-1:-1;;;12776:2:1;12761:18;;12754:45;12831:3;12816:19;;12430:411::o;13605:::-;13807:2;13789:21;;;13846:2;13826:18;;;13819:30;13885:34;13880:2;13865:18;;13858:62;-1:-1:-1;;;13951:2:1;13936:18;;13929:45;14006:3;13991:19;;13605:411::o;16312:340::-;16514:2;16496:21;;;16553:2;16533:18;;;16526:30;-1:-1:-1;;;16587:2:1;16572:18;;16565:46;16643:2;16628:18;;16312:340::o;16657:408::-;16859:2;16841:21;;;16898:2;16878:18;;;16871:30;16937:34;16932:2;16917:18;;16910:62;-1:-1:-1;;;17003:2:1;16988:18;;16981:42;17055:3;17040:19;;16657:408::o;20237:405::-;20439:2;20421:21;;;20478:2;20458:18;;;20451:30;20517:34;20512:2;20497:18;;20490:62;-1:-1:-1;;;20583:2:1;20568:18;;20561:39;20632:3;20617:19;;20237:405::o;24924:415::-;25126:2;25108:21;;;25165:2;25145:18;;;25138:30;25204:34;25199:2;25184:18;;25177:62;-1:-1:-1;;;25270:2:1;25255:18;;25248:49;25329:3;25314:19;;24924:415::o;26075:128::-;26115:3;26146:1;26142:6;26139:1;26136:13;26133:39;;;26152:18;;:::i;:::-;-1:-1:-1;26188:9:1;;26075:128::o;26208:422::-;26297:1;26340:5;26297:1;26354:270;26375:7;26365:8;26362:21;26354:270;;;26434:4;26430:1;26426:6;26422:17;26416:4;26413:27;26410:53;;;26443:18;;:::i;:::-;26493:7;26483:8;26479:22;26476:55;;;26513:16;;;;26476:55;26592:22;;;;26552:15;;;;26354:270;;;26358:3;26208:422;;;;;:::o;26635:140::-;26693:5;26722:47;26763:4;26753:8;26749:19;26743:4;26829:5;26859:8;26849:80;;-1:-1:-1;26900:1:1;26914:5;;26849:80;26948:4;26938:76;;-1:-1:-1;26985:1:1;26999:5;;26938:76;27030:4;27048:1;27043:59;;;;27116:1;27111:130;;;;27023:218;;27043:59;27073:1;27064:10;;27087:5;;;27111:130;27148:3;27138:8;27135:17;27132:43;;;27155:18;;:::i;:::-;-1:-1:-1;;27211:1:1;27197:16;;27226:5;;27023:218;;27325:2;27315:8;27312:16;27306:3;27300:4;27297:13;27293:36;27287:2;27277:8;27274:16;27269:2;27263:4;27260:12;27256:35;27253:77;27250:159;;;-1:-1:-1;27362:19:1;;;27394:5;;27250:159;27441:34;27466:8;27460:4;27441:34;:::i;:::-;27511:6;27507:1;27503:6;27499:19;27490:7;27487:32;27484:58;;;27522:18;;:::i;:::-;27560:20;;26780:806;-1:-1:-1;;;26780:806:1:o;27591:168::-;27631:7;27697:1;27693;27689:6;27685:14;27682:1;27679:21;27674:1;27667:9;27660:17;27656:45;27653:71;;;27704:18;;:::i;:::-;-1:-1:-1;27744:9:1;;27591:168::o;27764:125::-;27804:4;27832:1;27829;27826:8;27823:34;;;27837:18;;:::i;:::-;-1:-1:-1;27874:9:1;;27764:125::o;27894:258::-;27966:1;27976:113;27990:6;27987:1;27984:13;27976:113;;;28066:11;;;28060:18;28047:11;;;28040:39;28012:2;28005:10;27976:113;;;28107:6;28104:1;28101:13;28098:48;;;-1:-1:-1;;28142:1:1;28124:16;;28117:27;27894:258::o;28157:136::-;28196:3;28224:5;28214:39;;28233:18;;:::i;:::-;-1:-1:-1;;;28269:18:1;;28157:136::o;28298:380::-;28377:1;28373:12;;;;28420;;;28441:61;;28495:4;28487:6;28483:17;28473:27;;28441:61;28548:2;28540:6;28537:14;28517:18;28514:38;28511:161;;;28594:10;28589:3;28585:20;28582:1;28575:31;28629:4;28626:1;28619:15;28657:4;28654:1;28647:15;28511:161;;28298:380;;;:::o;28683:127::-;28744:10;28739:3;28735:20;28732:1;28725:31;28775:4;28772:1;28765:15;28799:4;28796:1;28789:15;28815:127;28876:10;28871:3;28867:20;28864:1;28857:31;28907:4;28904:1;28897:15;28931:4;28928:1;28921:15;28947:127;29008:10;29003:3;28999:20;28996:1;28989:31;29039:4;29036:1;29029:15;29063:4;29060:1;29053:15

Swarm Source

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