ETH Price: $1,968.47 (-0.27%)

Contract

0x0F276bef0dE8024c1ff983EDba87560a35e88e5F

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To
2543232025-01-27 18:08:2553 days ago1738001305  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
UpcadePointsViewFacet

Compiler Version
v0.8.28+commit.7893614a

ZkSolc Version
v1.5.7

Optimization Enabled:
Yes with Mode 3

Other Settings:
paris EvmVersion
File 1 of 19 : UpcadePointsViewFacet.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

// Local imports - Interfaces
import {IUpcadePointsViewFacet} from "../interfaces/IUpcadePointsViewFacet.sol";

// Local imports - Services
import {UpcadePointsViewService} from "../libraries/services/UpcadePointsViewService.sol";

// Local imports - Types
import {ResponseTypes} from "../types/ResponseTypes.sol";

/// @dev UpcadePointsViewFacet facet
contract UpcadePointsViewFacet is IUpcadePointsViewFacet {
    /**
     * @dev This function allows to fetch custom UpcadePointsCounterDto data for given user.
     *
     * @dev Parameters :
     * @param account User address
     *
     * @dev Returns :
     * @return UpcadePointsCounterDto custom struct
     */
    function getUserUpcadePointsCounterData(
        address account
    ) external view returns (ResponseTypes.UpcadePointsCounterDto memory) {
        return UpcadePointsViewService.getUpcadePointsCounterData(account);
    }

    /**
     * @dev This function allows to fetch total amount of upcadePoints for given user.
     *
     * @dev Parameters :
     * @param account User address
     *
     * @dev Returns :
     * @return Amount of user Upcade Points
     */
    function getUserTotalUpcadePoints(
        address account
    ) external view returns (uint256) {
        return UpcadePointsViewService.getTotalUpcadePoints(account);
    }

    /**
     * @dev This function allows to fetch custom UpcadePointsCounterDto data for given users.
     *
     * @dev Parameters :
     * @param accounts User addresses
     *
     * @dev Returns :
     * @return UpcadePointsCounterDto custom struct array
     */
    function getUsersUpcadePointsCounterData(
        address[] calldata accounts
    ) external view returns (ResponseTypes.UpcadePointsCounterDto[] memory) {
        // Users counter
        uint256 accountsLength = accounts.length;

        // Prepare response
        ResponseTypes.UpcadePointsCounterDto[]
            memory response = new ResponseTypes.UpcadePointsCounterDto[](
                accountsLength
            );

        // Fetch response data for each user
        for (uint256 i = 0; i < accountsLength; i++) {
            response[i] = UpcadePointsViewService.getUpcadePointsCounterData(
                accounts[i]
            );
        }

        // Return
        return response;
    }

    /**
     * @dev This function allows to fetch total amount of upcadePoints for given users.
     *
     * @dev Parameters :
     * @param accounts User addresses
     *
     * @dev Returns :
     * @return Amount of users Upcade Points
     */
    function getUsersTotalUpcadePoints(
        address[] calldata accounts
    ) external view returns (uint256[] memory) {
        // User counter
        uint256 accountsLength = accounts.length;

        // Prepare response
        uint256[] memory response = new uint256[](accountsLength);

        // Fetch response data for each user
        for (uint256 i = 0; i < accountsLength; i++) {
            response[i] = UpcadePointsViewService.getTotalUpcadePoints(
                accounts[i]
            );
        }

        // Return
        return response;
    }
}

File 2 of 19 : IUpcadePointsViewFacet.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

// Local imports - Types
import {ResponseTypes} from "../types/ResponseTypes.sol";

/// @dev IUpcadePointsViewFacet interface
interface IUpcadePointsViewFacet {
    /**
     * @dev This function allows to fetch custom UpcadePointsCounterDto data for given user.
     *
     * @dev Parameters :
     * @param account User address
     *
     * @dev Returns :
     * @return UpcadePointsCounterDto custom struct
     */
    function getUserUpcadePointsCounterData(
        address account
    ) external view returns (ResponseTypes.UpcadePointsCounterDto memory);

    /**
     * @dev This function allows to fetch total amount of Upcade Points for given user.
     *
     * @dev Parameters :
     * @param account User address
     *
     * @dev Returns :
     * @return Amount of user Upcade Points
     */
    function getUserTotalUpcadePoints(
        address account
    ) external view returns (uint256);

    /**
     * @dev This function allows to fetch custom UpcadePointsCounterDto data for given users.
     *
     * @dev Parameters :
     * @param accounts User addresses
     *
     * @dev Returns :
     * @return UpcadePointsCounterDto custom struct array
     */
    function getUsersUpcadePointsCounterData(
        address[] calldata accounts
    ) external view returns (ResponseTypes.UpcadePointsCounterDto[] memory);

    /**
     * @dev This function allows to fetch total amount of Upcade Points for given users.
     *
     * @dev Parameters :
     * @param accounts User addresses
     *
     * @dev Returns :
     * @return Amount of users Upcade Points
     */
    function getUsersTotalUpcadePoints(
        address[] calldata accounts
    ) external view returns (uint256[] memory);
}

File 3 of 19 : ResponseTypes.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

// Local imports - Types
import {EnumTypes} from "./EnumTypes.sol";

/// @dev ResponseTypes library
library ResponseTypes {
    struct TokenDto {
        address tokenAddress;
        string name;
        EnumTypes.TokenType tokenType;
        ERC20Details erc20Details;
        ERC721Details erc721Details;
        ERC1155IdDetails[] erc1155Details;
    }

    struct ERC20Details {
        uint256 decimals;
        uint256 upcadePointsPerToken;
        EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod;
    }

    struct ERC721Details {
        uint256 upcadePointsPerNft;
        EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod;
    }

    struct ERC1155IdDetails {
        string id;
        uint256 upcadePointsPerId;
        EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethodPerId;
    }

    struct UpcadePointsCounterDto {
        ERC20Dto[] erc20TokensData;
        ERC721Dto[] erc721TokensData;
        ERC1155Dto[] erc1155TokensData;
    }

    struct ERC20Dto {
        address tokenAddress;
        string tokenName;
        EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod;
        uint256 decimals;
        uint256 upcadePointsPerToken;
        uint256 userBalance;
    }

    struct ERC721Dto {
        address tokenAddress;
        string tokenName;
        EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod;
        uint256 upcadePointsPerNft;
        uint256 userBalance;
        bool isEnumerableSupported;
        uint256[] tokenIds;
        string[] tokenUris;
    }

    struct ERC1155Dto {
        address tokenAddress;
        string tokenName;
        string[] gameIds;
        string[] uris;
        EnumTypes.TokenUpcadePointsCalculationMethod[] upcadePointsCalculationMethodPerIds;
        uint256[] upcadePointsPerIds;
        uint256[] balances;
    }
}

File 4 of 19 : UpcadePointsViewService.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

// OpenZeppelin imports
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import {IERC1155MetadataURI} from "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";

// Local imports - Interfaces
import {IUpcadeProofOfGame} from "../../interfaces/IUpcadeProofOfGame.sol";

// Local imports = Storages
import {LibToken} from "../storages/LibToken.sol";
import {LibUpcadePoints} from "../storages/LibUpcadePoints.sol";

// Local imports - Services
import {ConversionService} from "./ConversionService.sol";

// Local imports - Types
import {EnumTypes} from "../../types/EnumTypes.sol";
import {ResponseTypes} from "../../types/ResponseTypes.sol";

/// @dev UpcadePointsViewService service
library UpcadePointsViewService {
    /**
     * @dev This function allows to fetch custom UpcadePointsCounterDto for given user.
     *
     * @dev Parameters :
     * @param account User address
     *
     * @dev Returns :
     * @return UpcadePointsCounterDto struct
     */
    function getUpcadePointsCounterData(
        address account
    ) internal view returns (ResponseTypes.UpcadePointsCounterDto memory) {
        ResponseTypes.UpcadePointsCounterDto memory response;

        address[] memory erc20TokenAddresses = LibToken
            .getERC20TokenAddresses();
        address[] memory erc721TokenAddresses = LibToken
            .getERC721TokenAddresses();
        address[] memory erc1155TokenAddresses = LibToken
            .getERC1155TokenAddresses();

        uint256 erc20TokenAddressesLength = erc20TokenAddresses.length;
        uint256 erc721TokenAddressesLength = erc721TokenAddresses.length;
        uint256 erc1155TokenAddressesLength = erc1155TokenAddresses.length;

        ResponseTypes.ERC20Dto[]
            memory erc20Dtos = new ResponseTypes.ERC20Dto[](
                erc20TokenAddressesLength
            );

        {
            for (uint256 i = 0; i < erc20TokenAddressesLength; i++) {
                erc20Dtos[i].tokenAddress = erc20TokenAddresses[i];
                erc20Dtos[i].tokenName = LibToken.getTokenName(
                    erc20TokenAddresses[i]
                );
                erc20Dtos[i].upcadePointsCalculationMethod = LibToken
                    .getERC20UpcadePointsCalculationMethod(
                        erc20TokenAddresses[i]
                    );
                erc20Dtos[i].decimals = IERC20Metadata(erc20TokenAddresses[i])
                    .decimals();
                erc20Dtos[i].upcadePointsPerToken = LibToken
                    .getERC20UpcadePointsPerToken(erc20TokenAddresses[i]);
                erc20Dtos[i].userBalance = IERC20(erc20TokenAddresses[i])
                    .balanceOf(account);
            }

            response.erc20TokensData = erc20Dtos;
        }

        ResponseTypes.ERC721Dto[]
            memory erc721Dtos = new ResponseTypes.ERC721Dto[](
                erc721TokenAddressesLength
            );

        {
            for (uint256 j = 0; j < erc721TokenAddressesLength; j++) {
                erc721Dtos[j].tokenAddress = erc721TokenAddresses[j];
                erc721Dtos[j].tokenName = LibToken.getTokenName(
                    erc721TokenAddresses[j]
                );
                erc721Dtos[j].upcadePointsCalculationMethod = LibToken
                    .getERC721UpcadePointsCalculationMethod(
                        erc721TokenAddresses[j]
                    );
                erc721Dtos[j].upcadePointsPerNft = LibToken
                    .getERC721UpcadePointsPerNft(erc721TokenAddresses[j]);
                erc721Dtos[j].userBalance = IERC721(erc721TokenAddresses[j])
                    .balanceOf(account);
                erc721Dtos[j].isEnumerableSupported = IERC721(
                    erc721TokenAddresses[j]
                ).supportsInterface(type(IERC721Enumerable).interfaceId);

                if (
                    erc721Dtos[j].userBalance > 0 &&
                    erc721Dtos[j].isEnumerableSupported
                ) {
                    erc721Dtos[j].tokenIds = new uint256[](
                        erc721Dtos[j].userBalance
                    );
                    erc721Dtos[j].tokenUris = new string[](
                        erc721Dtos[j].userBalance
                    );

                    for (uint256 k = 0; k < erc721Dtos[j].userBalance; k++) {
                        erc721Dtos[j].tokenIds[k] = IERC721Enumerable(
                            erc721TokenAddresses[j]
                        ).tokenOfOwnerByIndex(account, k);
                        erc721Dtos[j].tokenUris[k] = IERC721Metadata(
                            erc721TokenAddresses[j]
                        ).tokenURI(erc721Dtos[j].tokenIds[k]);
                    }
                }
            }

            response.erc721TokensData = erc721Dtos;
        }

        ResponseTypes.ERC1155Dto[]
            memory erc1155Dtos = new ResponseTypes.ERC1155Dto[](
                erc1155TokenAddressesLength
            );
        {
            for (uint256 l = 0; l < erc1155TokenAddressesLength; l++) {
                erc1155Dtos[l].tokenAddress = erc1155TokenAddresses[l];
                erc1155Dtos[l].tokenName = LibToken.getTokenName(
                    erc1155TokenAddresses[l]
                );
                erc1155Dtos[l].gameIds = LibToken.getERC1155Ids(
                    erc1155TokenAddresses[l]
                );
                erc1155Dtos[l].balances = IUpcadeProofOfGame(
                    erc1155TokenAddresses[l]
                ).balanceOfBatchByGameIds(account, erc1155Dtos[l].gameIds);

                uint256 erc1155BalancesLength = erc1155Dtos[l].balances.length;

                erc1155Dtos[l].uris = new string[](erc1155BalancesLength);
                erc1155Dtos[l]
                    .upcadePointsCalculationMethodPerIds = new EnumTypes.TokenUpcadePointsCalculationMethod[](
                    erc1155BalancesLength
                );
                erc1155Dtos[l].upcadePointsPerIds = new uint256[](
                    erc1155BalancesLength
                );

                for (uint256 m = 0; m < erc1155BalancesLength; m++) {
                    erc1155Dtos[l].uris[m] = IERC1155MetadataURI(
                        erc1155TokenAddresses[l]
                    ).uri(
                            ConversionService.convertGameIdToProofOfGameId(
                                erc1155Dtos[l].gameIds[m]
                            )
                        );
                    erc1155Dtos[l].upcadePointsCalculationMethodPerIds[
                        m
                    ] = LibToken.getERC1155UpcadePointsCalculationMethodPerId(
                        erc1155TokenAddresses[l],
                        erc1155Dtos[l].gameIds[m]
                    );
                    erc1155Dtos[l].upcadePointsPerIds[m] = LibToken
                        .getERC1155UpcadePointsPerId(
                            erc1155TokenAddresses[l],
                            erc1155Dtos[l].gameIds[m]
                        );
                }
            }

            response.erc1155TokensData = erc1155Dtos;
        }

        return response;
    }

    /**
     * @dev This function allows to fetch total amount of upcadePoints for given user.
     *
     * @dev Parameters :
     * @param account User address
     *
     * @dev Returns :
     * @return Total amount of user upcadePoints
     */
    function getTotalUpcadePoints(
        address account
    ) internal view returns (uint256) {
        uint256 totalUpcadePoints = LibUpcadePoints.getAdditionalUpcadePoints(
            account
        );

        address[] memory erc20TokenAddresses = LibToken
            .getERC20TokenAddresses();
        address[] memory erc721TokenAddresses = LibToken
            .getERC721TokenAddresses();
        address[] memory erc1155TokenAddresses = LibToken
            .getERC1155TokenAddresses();

        uint256 erc20TokenAddressesLength = erc20TokenAddresses.length;
        uint256 erc721TokenAddressesLength = erc721TokenAddresses.length;
        uint256 erc1155TokenAddressesLength = erc1155TokenAddresses.length;

        for (uint256 i = 0; i < erc20TokenAddressesLength; i++) {
            uint256 upcadePointsPerToken = LibToken
                .getERC20UpcadePointsPerToken(erc20TokenAddresses[i]);

            EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod = LibToken
                    .getERC20UpcadePointsCalculationMethod(
                        erc20TokenAddresses[i]
                    );

            uint256 erc20Balance = IERC20(erc20TokenAddresses[i]).balanceOf(
                account
            );

            if (erc20Balance > 0) {
                totalUpcadePoints += upcadePointsCalculationMethod ==
                    EnumTypes.TokenUpcadePointsCalculationMethod.SINGLE
                    ? upcadePointsPerToken
                    : (upcadePointsPerToken * erc20Balance) /
                        (10 **
                            LibToken.getERC20Decimals(erc20TokenAddresses[i]));
            }
        }

        for (uint256 j = 0; j < erc721TokenAddressesLength; j++) {
            uint256 upcadePointsPerNft = LibToken.getERC721UpcadePointsPerNft(
                erc721TokenAddresses[j]
            );

            EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod = LibToken
                    .getERC721UpcadePointsCalculationMethod(
                        erc721TokenAddresses[j]
                    );

            uint256 erc721Balance = IERC721(erc721TokenAddresses[j]).balanceOf(
                account
            );

            if (erc721Balance > 0) {
                totalUpcadePoints += upcadePointsCalculationMethod ==
                    EnumTypes.TokenUpcadePointsCalculationMethod.SINGLE
                    ? upcadePointsPerNft
                    : upcadePointsPerNft * erc721Balance;
            }
        }

        for (uint256 k = 0; k < erc1155TokenAddressesLength; k++) {
            string[] memory erc1155Ids = LibToken.getERC1155Ids(
                erc1155TokenAddresses[k]
            );

            uint256[] memory erc1155Balances = IUpcadeProofOfGame(
                erc1155TokenAddresses[k]
            ).balanceOfBatchByGameIds(account, erc1155Ids);

            uint256 erc1155BalancesLength = erc1155Balances.length;

            for (uint256 l = 0; l < erc1155BalancesLength; l++) {
                uint256 upcadePointsPerId = LibToken
                    .getERC1155UpcadePointsPerId(
                        erc1155TokenAddresses[k],
                        erc1155Ids[l]
                    );

                EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethodPerId = LibToken
                        .getERC1155UpcadePointsCalculationMethodPerId(
                            erc1155TokenAddresses[k],
                            erc1155Ids[l]
                        );

                if (erc1155Balances[l] > 0) {
                    totalUpcadePoints += upcadePointsCalculationMethodPerId ==
                        EnumTypes.TokenUpcadePointsCalculationMethod.SINGLE
                        ? upcadePointsPerId
                        : upcadePointsPerId * erc1155Balances[l];
                }
            }
        }

        return totalUpcadePoints;
    }
}

File 5 of 19 : IUpcadeProofOfGame.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

/// @dev IUpcadeProofOfGame interface used in 'UpcadeProofOfGame' contract.
interface IUpcadeProofOfGame {
    /**
     * @dev Allows to set URI for given token id.
     *
     * @dev Parameters :
     * @param _tokenId - Token id
     * @param _uri - New URI
     */
    function setURI(uint256 _tokenId, string memory _uri) external;

    /**
     * @dev Allows to mint new tokens for single id.
     *
     * @dev Parameters :
     * @param _to - New tokens receiver address
     * @param _id - Token id
     * @param _value - Amount of tokens to mint
     * @param _data - Additional data (for these contract probably always empty value
     * will be passed)
     */
    function mint(
        address _to,
        uint256 _id,
        uint256 _value,
        bytes memory _data
    ) external;

    /**
     * @dev Allows to mint new tokens for multiple ids (in batch).
     *
     * @dev Parameters :
     * @param _to - New tokens receiver address
     * @param _ids - Token ids
     * @param _values - Amount of tokens to mint
     * @param _data - Additional data (for these contract probably always empty value
     * will be passed)
     */
    function mintBatch(
        address _to,
        uint256[] memory _ids,
        uint256[] memory _values,
        bytes memory _data
    ) external;

    /**
     * @dev Allows to fetch balance for given user by Upcade game id.
     *
     * @dev Parameters :
     * @param _account - User address
     * @param _gameId - Upcade game id
     *
     * @dev Returns :
     * @return User balance
     */
    function balanceOfByGameId(
        address _account,
        string memory _gameId
    ) external view returns (uint256);

    /**
     * @dev Allows to fetch balance for given user by Upcade game ids (in batch).
     *
     * @dev Parameters :
     * @param _account - User address
     * @param _gameIds - Upcade game ids
     *
     * @dev Returns :
     * @return User balance for given game ids
     */
    function balanceOfBatchByGameIds(
        address _account,
        string[] memory _gameIds
    ) external view returns (uint256[] memory);
}

File 6 of 19 : EnumTypes.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

/// @dev EnumTypes library
library EnumTypes {
    enum TokenType {
        ERC20,
        ERC721,
        ERC1155
    }

    enum TokenUpcadePointsCalculationMethod {
        SINGLE,
        ALL
    }
}

File 7 of 19 : LibToken.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

// Local imports - Errors
import {TokenErrors} from "../../errors/TokenErrors.sol";

// Local imports - Types
import {StorageTypes} from "../../types/StorageTypes.sol";
import {EnumTypes} from "../../types/EnumTypes.sol";

/// @dev LibToken storage library
library LibToken {
    /// @dev 32 bytes keccak hash of a string to use as a token storage location
    bytes32 constant TOKEN_STORAGE_POSITION = keccak256("upcade.points.token");
    /// @dev 32 bytes keccak hash of a string to use as a all ERC-20 storage addresses location
    bytes32 constant ERC20_KEY = keccak256("ERC20");
    /// @dev 32 bytes keccak hash of a string to use as a all ERC-721 storage addresses location
    bytes32 constant ERC721_KEY = keccak256("ERC721");
    /// @dev 32 bytes keccak hash of a string to use as a all ERC-1155 storage addresses location
    bytes32 constant ERC1155_KEY = keccak256("ERC1155");

    /// @dev Storage TokenStorage struct
    struct TokenStorage {
        /// @dev ERC-20 token addresses
        mapping(bytes32 => address[]) erc20TokenAddresses;
        /// @dev ERC-721 token addresses
        mapping(bytes32 => address[]) erc721TokenAddresses;
        /// @dev ERC-1155 token addresses
        mapping(bytes32 => address[]) erc1155TokenAddresses;
        /// @dev Tokens
        mapping(address => StorageTypes.Token) tokens;
        /// @dev ERC-20 tokens
        mapping(address => StorageTypes.ERC20) erc20Tokens;
        /// @dev ERC-721 tokens
        mapping(address => StorageTypes.ERC721) erc721Tokens;
        /// @dev ERC-1155 tokens
        mapping(address => StorageTypes.ERC1155) erc1155Tokens;
        /// @dev ERC-1155 token ids
        mapping(address => StorageTypes.ERC1155Details) erc1155Details;
    }

    /// @dev Allows to fetch token storage
    function tokenStorage() internal pure returns (TokenStorage storage ts) {
        bytes32 position = TOKEN_STORAGE_POSITION;
        // assigns struct storage slot to the storage position
        assembly {
            ts.slot := position
        }
    }

    /**************************************************************\
    *                           Getters                                    
    /**************************************************************/

    /**
     * @dev This function allows to fetch all ERC-20 token addresses.
     *
     * @dev Returns :
     * @return Array of addresses
     */
    function getERC20TokenAddresses() internal view returns (address[] memory) {
        return tokenStorage().erc20TokenAddresses[ERC20_KEY];
    }

    /**
     * @dev This function allows to fetch all ERC-721 token addresses.
     *
     * @dev Returns :
     * @return Array of addresses
     */
    function getERC721TokenAddresses()
        internal
        view
        returns (address[] memory)
    {
        return tokenStorage().erc721TokenAddresses[ERC721_KEY];
    }

    /**
     * @dev This function allows to fetch all ERC-1155 token addresses.
     *
     * @dev Returns :
     * @return Array of addresses
     */
    function getERC1155TokenAddresses()
        internal
        view
        returns (address[] memory)
    {
        return tokenStorage().erc1155TokenAddresses[ERC1155_KEY];
    }

    /**
     * @dev This function allows to fetch all token address for given address
     *      (used in validations).
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return Token address
     */
    function getTokenAddress(
        address tokenAddress
    ) internal view returns (address) {
        return tokenStorage().tokens[tokenAddress].tokenAddress;
    }

    /**
     * @dev This function allows to fetch token struct for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return Token struct
     */
    function getToken(
        address tokenAddress
    ) internal view returns (StorageTypes.Token memory) {
        return tokenStorage().tokens[tokenAddress];
    }

    /**
     * @dev This function allows to fetch token name for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return Token name
     */
    function getTokenName(
        address tokenAddress
    ) internal view returns (string memory) {
        return tokenStorage().tokens[tokenAddress].name;
    }

    /**
     * @dev This function allows to fetch token type for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return Token type
     */
    function getTokenType(
        address tokenAddress
    ) internal view returns (EnumTypes.TokenType) {
        return tokenStorage().tokens[tokenAddress].tokenType;
    }

    /**
     * @dev This function allows to fetch ERC-20 token data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-20 struct
     */
    function getERC20Token(
        address tokenAddress
    ) internal view returns (StorageTypes.ERC20 memory) {
        return tokenStorage().erc20Tokens[tokenAddress];
    }

    /**
     * @dev This function allows to fetch ERC-20 token decimals for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-20 decimals
     */
    function getERC20Decimals(
        address tokenAddress
    ) internal view returns (uint256) {
        return tokenStorage().erc20Tokens[tokenAddress].decimals;
    }

    /**
     * @dev This function allows to fetch ERC-20 Upcade Points per token for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-20 Upcade Points per token
     */
    function getERC20UpcadePointsPerToken(
        address tokenAddress
    ) internal view returns (uint256) {
        return tokenStorage().erc20Tokens[tokenAddress].upcadePointsPerToken;
    }

    /**
     * @dev This function allows to fetch ERC-20 Upcade Points calculation method for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-20 Upcade Points calculation method
     */
    function getERC20UpcadePointsCalculationMethod(
        address tokenAddress
    ) internal view returns (EnumTypes.TokenUpcadePointsCalculationMethod) {
        return
            tokenStorage()
                .erc20Tokens[tokenAddress]
                .upcadePointsCalculationMethod;
    }

    /**
     * @dev This function allows to fetch ERC-721 token data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-721 struct
     */
    function getERC721Token(
        address tokenAddress
    ) internal view returns (StorageTypes.ERC721 memory) {
        return tokenStorage().erc721Tokens[tokenAddress];
    }

    /**
     * @dev This function allows to fetch ERC-721 Upcade Points per NFT for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-721 Upcade Points per NFT
     */
    function getERC721UpcadePointsPerNft(
        address tokenAddress
    ) internal view returns (uint256) {
        return tokenStorage().erc721Tokens[tokenAddress].upcadePointsPerNft;
    }

    /**
     * @dev This function allows to fetch ERC-721 Upcade Points calculation method for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-721 Upcade Points calculation method
     */
    function getERC721UpcadePointsCalculationMethod(
        address tokenAddress
    ) internal view returns (EnumTypes.TokenUpcadePointsCalculationMethod) {
        return
            tokenStorage()
                .erc721Tokens[tokenAddress]
                .upcadePointsCalculationMethod;
    }

    /**
     * @dev This function allows to fetch ERC-1155 token data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-1155 struct
     */
    function getERC1155Token(
        address tokenAddress
    ) internal view returns (StorageTypes.ERC1155 storage) {
        return tokenStorage().erc1155Tokens[tokenAddress];
    }

    /**
     * @dev This function allows to fetch ERC-1155 is id whitelisted for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-1155 is id whitelisted
     */
    function getERC1155IdWhitelisted(
        address tokenAddress,
        string memory id
    ) internal view returns (bool) {
        return tokenStorage().erc1155Details[tokenAddress].isIdWhitelisted[id];
    }

    /**
     * @dev This function allows to fetch ERC-1155 Upcade Points per id for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-1155 id Upcade Points per id
     */
    function getERC1155UpcadePointsPerId(
        address tokenAddress,
        string memory id
    ) internal view returns (uint256) {
        return
            tokenStorage().erc1155Details[tokenAddress].upcadePointsPerId[id];
    }

    /**
     * @dev This function allows to fetch ERC-1155 Upcade Points calculation method per id for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return ERC-1155 id Upcade Points calculation method
     */
    function getERC1155UpcadePointsCalculationMethodPerId(
        address tokenAddress,
        string memory id
    ) internal view returns (EnumTypes.TokenUpcadePointsCalculationMethod) {
        return
            tokenStorage()
                .erc1155Details[tokenAddress]
                .upcadePointsCalculationMethodPerId[id];
    }

    /**
     * @dev This function allows to fetch all ERC-1155 ids for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     *
     * @dev Returns :
     * @return Array of ERC-1155 ids
     */
    function getERC1155Ids(
        address tokenAddress
    ) internal view returns (string[] memory) {
        return tokenStorage().erc1155Tokens[tokenAddress].ids;
    }

    /**
     * @dev This function allows to fetch ERC-1155 id name for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param index Index of ids array
     *
     * @dev Returns :
     * @return ERC-1155 id name
     */
    function getERC1155IdName(
        address tokenAddress,
        uint256 index
    ) internal view returns (string memory) {
        return tokenStorage().erc1155Tokens[tokenAddress].ids[index];
    }

    /**************************************************************\
    *                           Setters                                    
    /**************************************************************/

    /**
     * @dev This function allows to set ERC-1155 is whitelisted for id.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param id ERC-1155 id
     * @param isWhitelisted Is id whitelited
     */
    function setERC1155IdWhitelisted(
        address tokenAddress,
        string memory id,
        bool isWhitelisted
    ) internal {
        tokenStorage().erc1155Details[tokenAddress].isIdWhitelisted[
            id
        ] = isWhitelisted;
    }

    /**
     * @dev This function allows to set ERC-1155 Upcade Points per id for id.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param id ERC-1155 id
     * @param upcadePointsPerId Upcade Points per id
     */
    function setERC1155UpcadePointsPerId(
        address tokenAddress,
        string memory id,
        uint256 upcadePointsPerId
    ) internal {
        tokenStorage().erc1155Details[tokenAddress].upcadePointsPerId[
            id
        ] = upcadePointsPerId;
    }

    /**
     * @dev This function allows to set ERC-1155 Upcade Points calculation method for id.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param id ERC-1155 id
     * @param upcadePointsCalculationMethod UpcadePoints calculation method
     */
    function setERC1155UpcadePointsCalculationMethodPerId(
        address tokenAddress,
        string memory id,
        EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod
    ) internal {
        tokenStorage()
            .erc1155Details[tokenAddress]
            .upcadePointsCalculationMethodPerId[
                id
            ] = upcadePointsCalculationMethod;
    }

    /**
     * @dev This function allows to set Token struct for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param token Token struct
     */
    function addToken(
        address tokenAddress,
        StorageTypes.Token memory token
    ) internal {
        tokenStorage().tokens[tokenAddress] = token;
    }

    /**
     * @dev This function allows to set ERC20 struct for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param erc20 ERC20 struct
     */
    function addERC20(
        address tokenAddress,
        StorageTypes.ERC20 memory erc20
    ) internal {
        tokenStorage().erc20TokenAddresses[ERC20_KEY].push(tokenAddress);
        tokenStorage().erc20Tokens[tokenAddress] = erc20;
    }

    /**
     * @dev This function allows to set ERC721 struct for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param erc721 ERC721 struct
     */
    function addERC721(
        address tokenAddress,
        StorageTypes.ERC721 memory erc721
    ) internal {
        tokenStorage().erc721TokenAddresses[ERC721_KEY].push(tokenAddress);
        tokenStorage().erc721Tokens[tokenAddress] = erc721;
    }

    /**
     * @dev This function allows to set ERC1155 struct and ids data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param erc1155 ERC1155 struct
     * @param upcadePointsPerId Array of upcadePoints per id
     * @param upcadePointsCalculationMethodPerId Array of upcadePoints calculation methods
     */
    function addERC1155(
        address tokenAddress,
        StorageTypes.ERC1155 memory erc1155,
        uint256[] memory upcadePointsPerId,
        EnumTypes.TokenUpcadePointsCalculationMethod[]
            memory upcadePointsCalculationMethodPerId
    ) internal {
        tokenStorage().erc1155TokenAddresses[ERC1155_KEY].push(tokenAddress);
        tokenStorage().erc1155Tokens[tokenAddress] = erc1155;

        uint256 idsLength = erc1155.ids.length;

        for (uint i = 0; i < idsLength; i++) {
            string memory id = erc1155.ids[i];

            setERC1155IdWhitelisted(tokenAddress, id, true);
            setERC1155UpcadePointsPerId(tokenAddress, id, upcadePointsPerId[i]);
            setERC1155UpcadePointsCalculationMethodPerId(
                tokenAddress,
                id,
                upcadePointsCalculationMethodPerId[i]
            );
        }
    }

    /**
     * @dev This function allows to add new ERC1155 ids data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param ids Array of ids
     * @param upcadePointsPerId Array of Upcade Points per id
     * @param upcadePointsCalculationMethodPerId Array of Upcade Points calculation methods
     */
    function addERC1155Ids(
        address tokenAddress,
        string[] memory ids,
        uint256[] memory upcadePointsPerId,
        EnumTypes.TokenUpcadePointsCalculationMethod[]
            memory upcadePointsCalculationMethodPerId
    ) internal {
        uint256 idsLength = ids.length;

        for (uint i = 0; i < idsLength; i++) {
            tokenStorage().erc1155Tokens[tokenAddress].ids.push(ids[i]);

            setERC1155IdWhitelisted(tokenAddress, ids[i], true);
            setERC1155UpcadePointsPerId(
                tokenAddress,
                ids[i],
                upcadePointsPerId[i]
            );
            setERC1155UpcadePointsCalculationMethodPerId(
                tokenAddress,
                ids[i],
                upcadePointsCalculationMethodPerId[i]
            );
        }
    }

    /**
     * @dev This function allows to remove Token struct for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     */
    function removeToken(address tokenAddress) internal {
        tokenStorage().tokens[tokenAddress] = StorageTypes.Token({
            tokenAddress: address(0),
            name: "",
            tokenType: EnumTypes.TokenType.ERC20 // default value
        });
    }

    /**
     * @dev This function allows to remove ERC20 struct and all ERC-20 data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     */
    function removeERC20(address tokenAddress) internal {
        tokenStorage().erc20Tokens[tokenAddress] = StorageTypes.ERC20({
            decimals: 0,
            upcadePointsPerToken: 0,
            upcadePointsCalculationMethod: EnumTypes
                .TokenUpcadePointsCalculationMethod
                .SINGLE
        });

        uint256 erc20TokenAddressesStorageLength = tokenStorage()
            .erc20TokenAddresses[ERC20_KEY]
            .length;

        if (erc20TokenAddressesStorageLength > 1) {
            for (uint256 i = 0; i < erc20TokenAddressesStorageLength; i++) {
                if (
                    tokenStorage().erc20TokenAddresses[ERC20_KEY][i] ==
                    tokenAddress
                ) {
                    tokenStorage().erc20TokenAddresses[ERC20_KEY][
                        i
                    ] = tokenStorage().erc20TokenAddresses[ERC20_KEY][
                        erc20TokenAddressesStorageLength - 1
                    ];
                    tokenStorage().erc20TokenAddresses[ERC20_KEY].pop();
                    break;
                }
            }

            uint256 erc20TokenAddressesStorageLengthAfterRemove = tokenStorage()
                .erc20TokenAddresses[ERC20_KEY]
                .length;

            if (
                erc20TokenAddressesStorageLength ==
                erc20TokenAddressesStorageLengthAfterRemove
            ) {
                revert TokenErrors.TokenNotFound(tokenAddress);
            }
        } else {
            if (
                tokenStorage().erc20TokenAddresses[ERC20_KEY][0] != tokenAddress
            ) {
                revert TokenErrors.TokenNotFound(tokenAddress);
            }

            tokenStorage().erc20TokenAddresses[ERC20_KEY].pop();
        }
    }

    /**
     * @dev This function allows to remove ERC721 struct and all ERC-721 data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     */
    function removeERC721(address tokenAddress) internal {
        tokenStorage().erc721Tokens[tokenAddress] = StorageTypes.ERC721({
            upcadePointsPerNft: 0,
            upcadePointsCalculationMethod: EnumTypes
                .TokenUpcadePointsCalculationMethod
                .SINGLE
        });

        uint256 erc721TokenAddressesStorageLength = tokenStorage()
            .erc721TokenAddresses[ERC721_KEY]
            .length;

        if (erc721TokenAddressesStorageLength > 1) {
            for (uint256 i = 0; i < erc721TokenAddressesStorageLength; i++) {
                if (
                    tokenStorage().erc721TokenAddresses[ERC721_KEY][i] ==
                    tokenAddress
                ) {
                    tokenStorage().erc721TokenAddresses[ERC721_KEY][
                        i
                    ] = tokenStorage().erc721TokenAddresses[ERC721_KEY][
                        erc721TokenAddressesStorageLength - 1
                    ];
                    tokenStorage().erc721TokenAddresses[ERC721_KEY].pop();
                    break;
                }
            }

            uint256 erc721TokenAddressesStorageLengthAfterRemove = tokenStorage()
                    .erc721TokenAddresses[ERC721_KEY]
                    .length;

            if (
                erc721TokenAddressesStorageLength ==
                erc721TokenAddressesStorageLengthAfterRemove
            ) {
                revert TokenErrors.TokenNotFound(tokenAddress);
            }
        } else {
            if (
                tokenStorage().erc721TokenAddresses[ERC721_KEY][0] !=
                tokenAddress
            ) {
                revert TokenErrors.TokenNotFound(tokenAddress);
            }

            tokenStorage().erc721TokenAddresses[ERC721_KEY].pop();
        }
    }

    /**
     * @dev This function allows to remove all ERC-1155 data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     */
    function removeERC1155(address tokenAddress) internal {
        uint256 erc1155TokenAddressesStorageLength = tokenStorage()
            .erc1155TokenAddresses[ERC1155_KEY]
            .length;

        if (erc1155TokenAddressesStorageLength > 1) {
            for (uint256 i = 0; i < erc1155TokenAddressesStorageLength; i++) {
                if (
                    tokenStorage().erc1155TokenAddresses[ERC1155_KEY][i] ==
                    tokenAddress
                ) {
                    tokenStorage().erc1155TokenAddresses[ERC1155_KEY][
                        i
                    ] = tokenStorage().erc1155TokenAddresses[ERC1155_KEY][
                        erc1155TokenAddressesStorageLength - 1
                    ];
                    tokenStorage().erc1155TokenAddresses[ERC1155_KEY].pop();
                    break;
                }
            }

            uint256 erc1155TokenAddressesStorageLengthAfterRemove = tokenStorage()
                    .erc1155TokenAddresses[ERC1155_KEY]
                    .length;

            if (
                erc1155TokenAddressesStorageLength ==
                erc1155TokenAddressesStorageLengthAfterRemove
            ) {
                revert TokenErrors.TokenNotFound(tokenAddress);
            }
        } else {
            if (
                tokenStorage().erc1155TokenAddresses[ERC1155_KEY][0] !=
                tokenAddress
            ) {
                revert TokenErrors.TokenNotFound(tokenAddress);
            }

            tokenStorage().erc1155TokenAddresses[ERC1155_KEY].pop();
        }

        uint256 idsLength = tokenStorage()
            .erc1155Tokens[tokenAddress]
            .ids
            .length;

        for (uint j = 0; j < idsLength; j++) {
            string memory id = tokenStorage().erc1155Tokens[tokenAddress].ids[
                j
            ];

            setERC1155IdWhitelisted(tokenAddress, id, false);
            setERC1155UpcadePointsPerId(tokenAddress, id, 0);
            setERC1155UpcadePointsCalculationMethodPerId(
                tokenAddress,
                id,
                EnumTypes.TokenUpcadePointsCalculationMethod.SINGLE
            );
        }

        delete tokenStorage().erc1155Tokens[tokenAddress].ids;
    }

    /**
     * @dev This function allows to remove ERC-1155 ids data for given address.
     *
     * @dev Parameters :
     * @param tokenAddress Token address
     * @param ids Array of ids
     */
    function removeERC1155Ids(
        address tokenAddress,
        string[] memory ids
    ) internal {
        uint256 idsLength = ids.length;

        for (uint i = 0; i < idsLength; i++) {
            uint256 idsStorageLength = tokenStorage()
                .erc1155Tokens[tokenAddress]
                .ids
                .length;

            if (idsStorageLength > 1) {
                for (uint256 j = 0; j < idsStorageLength; j++) {
                    if (
                        keccak256(
                            abi.encodePacked(
                                tokenStorage().erc1155Tokens[tokenAddress].ids[
                                    j
                                ]
                            )
                        ) == keccak256(abi.encodePacked(ids[i]))
                    ) {
                        tokenStorage().erc1155Tokens[tokenAddress].ids[
                            j
                        ] = tokenStorage().erc1155Tokens[tokenAddress].ids[
                            idsStorageLength - 1
                        ];

                        setERC1155IdWhitelisted(tokenAddress, ids[i], false);
                        setERC1155UpcadePointsPerId(tokenAddress, ids[i], 0);
                        setERC1155UpcadePointsCalculationMethodPerId(
                            tokenAddress,
                            ids[i],
                            EnumTypes.TokenUpcadePointsCalculationMethod.SINGLE
                        );

                        tokenStorage().erc1155Tokens[tokenAddress].ids.pop();

                        break;
                    }
                }

                uint256 idsStorageLengthAfterRemove = tokenStorage()
                    .erc1155Tokens[tokenAddress]
                    .ids
                    .length;

                if (idsStorageLengthAfterRemove == idsStorageLength) {
                    revert TokenErrors.ERC1155IdNotFound(tokenAddress, ids[i]);
                }
            } else {
                if (
                    keccak256(
                        abi.encodePacked(
                            tokenStorage().erc1155Tokens[tokenAddress].ids[0]
                        )
                    ) == keccak256(abi.encodePacked(ids[0]))
                ) {
                    revert TokenErrors.ERC1155IdNotFound(tokenAddress, ids[0]);
                }

                setERC1155IdWhitelisted(tokenAddress, ids[i], false);
                setERC1155UpcadePointsPerId(tokenAddress, ids[i], 0);
                setERC1155UpcadePointsCalculationMethodPerId(
                    tokenAddress,
                    ids[i],
                    EnumTypes.TokenUpcadePointsCalculationMethod.SINGLE
                );

                tokenStorage().erc1155Tokens[tokenAddress].ids.pop();
            }
        }
    }
}

File 8 of 19 : LibUpcadePoints.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

// Local imports - Types
import {StorageTypes} from "../../types/StorageTypes.sol";

/// @dev LibUpcadePoints storage library
library LibUpcadePoints {
    // 32 bytes keccak hash of a string to use as a upcade points storage location.
    bytes32 constant UPCADE_POINT_STORAGE_POSITION = keccak256("upcade.points");

    /// @dev Storage UpcadePointsStorage struct
    struct UpcadePointsStorage {
        /// @dev UpcadePoints
        mapping(address => StorageTypes.WalletUpcadePoints) upcadePoints;
    }

    /// @dev Allows to fetch upcadePoints storage
    function upcadePointsStorage()
        internal
        pure
        returns (UpcadePointsStorage storage bs)
    {
        bytes32 position = UPCADE_POINT_STORAGE_POSITION;
        // assigns struct storage slot to the storage position
        assembly {
            bs.slot := position
        }
    }

    /**************************************************************\
    *                           Getters                                    
    /**************************************************************/

    /**
     * @dev This function allows to fetch add additional Upcade Points for user.
     *
     * @dev Parameters :
     * @param user User address
     *
     * @dev Returns :
     * @return Amount of additional Upcade Points
     */
    function getAdditionalUpcadePoints(
        address user
    ) internal view returns (uint256) {
        return upcadePointsStorage().upcadePoints[user].additionalUpcadePoints;
    }

    /**************************************************************\
    *                           Setters                                    
    /**************************************************************/

    /**
     * @dev This function allows to add additional Upcade Points for user.
     *
     * @dev Parameters :
     * @param account User address
     * @param upcadePoints Amount of upcadePoints
     */
    function addAdditionalUpcadePoints(
        address account,
        uint256 upcadePoints
    ) internal {
        upcadePointsStorage()
            .upcadePoints[account]
            .additionalUpcadePoints += upcadePoints;
    }
}

File 9 of 19 : ConversionService.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

/// @dev This library contains funcionality to convert Upcade game ids to 'ProofOfGame' ids.
library ConversionService {
    /**
     * @dev Allows to convert Upcade game id to ERC-1155 'ProofOfGame' id
     *
     * @dev Parameters :
     * @param _gameId - Upcade game id
     *
     * @dev Returns :
     * @return 'ProofOfGame' id
     */
    function convertGameIdToProofOfGameId(
        string memory _gameId
    ) internal pure returns (uint256) {
        return uint256(keccak256(abi.encode(_gameId)));
    }
}

File 10 of 19 : TokenErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

/// @dev TokenErrors library
library TokenErrors {
    /// @dev CannotBeAddressZero error
    error CannotBeAddressZero();

    /**
     * @dev TokenAlreadyAdded error
     *
     * @dev Parameters :
     * @param tokenAddress Address of existed token
     */
    error TokenAlreadyAdded(address tokenAddress);

    /**
     * @dev TokenNotFound error
     *
     * @dev Parameters :
     * @param tokenAddress Address of token which hasn't been added
     */
    error TokenNotFound(address tokenAddress);

    /**
     * @dev TokenNotAdded error
     *
     * @dev Parameters :
     * @param tokenAddress Address of token which hasn't been added
     */
    error TokenNotAdded(address tokenAddress);

    /**
     * @dev ERC1155IdNotFound error
     *
     * @dev Parameters :
     * @param tokenAddress Address of the ERC-1155 token
     * @param id Id of ERC-1155 token which hasn't been added
     */
    error ERC1155IdNotFound(address tokenAddress, string id);

    /**
     * @dev ERC1155IdNotFound error
     *
     * @dev Parameters :
     * @param tokenAddress Address of the ERC-1155 token
     * @param id Id of ERC-1155 token which has been added already
     */
    error ERC1155IdAlreadyAdded(address tokenAddress, string id);

    /**
     * @dev ERC1155IdNotFound error
     *
     * @dev Parameters :
     * @param tokenAddress Address of the ERC-1155 token
     * @param id Id of ERC-1155 token which hasn't been added
     */
    error ERC1155IdNotAdded(address tokenAddress, string id);

    /// @dev ERC1155IdsCannotBeEmpty error
    error ERC1155IdsCannotBeEmpty();
}

File 11 of 19 : StorageTypes.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

// Local imports - Types
import {EnumTypes} from "./EnumTypes.sol";

/// @dev StorageTypes library
library StorageTypes {
    struct Token {
        address tokenAddress;
        string name;
        EnumTypes.TokenType tokenType;
    }

    struct ERC20 {
        uint256 decimals;
        uint256 upcadePointsPerToken;
        EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod;
    }

    struct ERC721 {
        uint256 upcadePointsPerNft;
        EnumTypes.TokenUpcadePointsCalculationMethod upcadePointsCalculationMethod;
    }

    struct ERC1155 {
        string[] ids;
    }

    struct ERC1155Details {
        mapping(string => bool) isIdWhitelisted;
        mapping(string => uint256) upcadePointsPerId;
        mapping(string => EnumTypes.TokenUpcadePointsCalculationMethod) upcadePointsCalculationMethodPerId;
    }

    struct WalletUpcadePoints {
        uint256 additionalUpcadePoints;
    }

    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }
}

File 12 of 19 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

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

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

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

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

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

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

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

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

File 13 of 19 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../utils/introspection/IERC165.sol";

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

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

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

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

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

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

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

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

    /**
     * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
     *
     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens
     * to an untrusted contract, when invoking {onERC1155Received} on the receiver.
     * Ensure to follow the checks-effects-interactions pattern and consider employing
     * reentrancy guards when interacting with untrusted contracts.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `value` amount.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens
     * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver.
     * Ensure to follow the checks-effects-interactions pattern and consider employing
     * reentrancy guards when interacting with untrusted contracts.
     *
     * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments.
     *
     * Requirements:
     *
     * - `ids` and `values` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external;
}

File 14 of 19 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC-721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
     *   a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC-721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
     *   {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
     *   a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the address zero.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

File 15 of 19 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

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

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

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

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

File 16 of 19 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.20;

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

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

File 17 of 19 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.20;

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

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 18 of 19 : IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.20;

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

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

File 19 of 19 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * 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[ERC 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);
}

Settings
{
  "evmVersion": "paris",
  "optimizer": {
    "enabled": true,
    "mode": "3"
  },
  "outputSelection": {
    "*": {
      "*": [
        "abi",
        "metadata"
      ],
      "": [
        "ast"
      ]
    }
  },
  "detectMissingLibraries": false,
  "forceEVMLA": false,
  "enableEraVMExtensions": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getUserTotalUpcadePoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getUserUpcadePointsCounterData","outputs":[{"components":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"enum EnumTypes.TokenUpcadePointsCalculationMethod","name":"upcadePointsCalculationMethod","type":"uint8"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"uint256","name":"upcadePointsPerToken","type":"uint256"},{"internalType":"uint256","name":"userBalance","type":"uint256"}],"internalType":"struct ResponseTypes.ERC20Dto[]","name":"erc20TokensData","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"enum EnumTypes.TokenUpcadePointsCalculationMethod","name":"upcadePointsCalculationMethod","type":"uint8"},{"internalType":"uint256","name":"upcadePointsPerNft","type":"uint256"},{"internalType":"uint256","name":"userBalance","type":"uint256"},{"internalType":"bool","name":"isEnumerableSupported","type":"bool"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"tokenUris","type":"string[]"}],"internalType":"struct ResponseTypes.ERC721Dto[]","name":"erc721TokensData","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string[]","name":"gameIds","type":"string[]"},{"internalType":"string[]","name":"uris","type":"string[]"},{"internalType":"enum EnumTypes.TokenUpcadePointsCalculationMethod[]","name":"upcadePointsCalculationMethodPerIds","type":"uint8[]"},{"internalType":"uint256[]","name":"upcadePointsPerIds","type":"uint256[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"internalType":"struct ResponseTypes.ERC1155Dto[]","name":"erc1155TokensData","type":"tuple[]"}],"internalType":"struct ResponseTypes.UpcadePointsCounterDto","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"getUsersTotalUpcadePoints","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"getUsersUpcadePointsCounterData","outputs":[{"components":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"enum EnumTypes.TokenUpcadePointsCalculationMethod","name":"upcadePointsCalculationMethod","type":"uint8"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"uint256","name":"upcadePointsPerToken","type":"uint256"},{"internalType":"uint256","name":"userBalance","type":"uint256"}],"internalType":"struct ResponseTypes.ERC20Dto[]","name":"erc20TokensData","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"enum EnumTypes.TokenUpcadePointsCalculationMethod","name":"upcadePointsCalculationMethod","type":"uint8"},{"internalType":"uint256","name":"upcadePointsPerNft","type":"uint256"},{"internalType":"uint256","name":"userBalance","type":"uint256"},{"internalType":"bool","name":"isEnumerableSupported","type":"bool"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"tokenUris","type":"string[]"}],"internalType":"struct ResponseTypes.ERC721Dto[]","name":"erc721TokensData","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string[]","name":"gameIds","type":"string[]"},{"internalType":"string[]","name":"uris","type":"string[]"},{"internalType":"enum EnumTypes.TokenUpcadePointsCalculationMethod[]","name":"upcadePointsCalculationMethodPerIds","type":"uint8[]"},{"internalType":"uint256[]","name":"upcadePointsPerIds","type":"uint256[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"internalType":"struct ResponseTypes.ERC1155Dto[]","name":"erc1155TokensData","type":"tuple[]"}],"internalType":"struct ResponseTypes.UpcadePointsCounterDto[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"}]

9c4d535b0000000000000000000000000000000000000000000000000000000000000000010005bf9c86fd1f4ff797dc6b79a9bfeeb6cf29070c63f70b548d75ade42aa400000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x0004000000000002001500000000000200000060031002700000058a0030019d0000058a03300197000300000031035500020000000103550000008004000039000000400040043f0000000100200190000000540000c13d000000040030008c000000a50000413d000000000201043b000000e0022002700000058c0020009c0000005c0000213d0000058f0020009c000000710000613d000005900020009c000000a50000c13d000000240030008c000000a50000413d0000000002000416000000000002004b000000a50000c13d0000000402100370000000000202043b000005930020009c000000a50000213d0000002304200039000000000034004b000000a50000813d0000000404200039000000000441034f000000000404043b000200000004001d000005930040009c000000a50000213d000100240020003d000000020200002900000005022002100000000104200029000000000034004b000000a50000213d0000003f042000390000059404400197000005950040009c000004c70000213d0000008004400039000000400040043f0000000204000029000000800040043f0000001f0420018f000000000002004b0000003f0000613d000000000131034f000000a002200039000000a003000039000000001501043c0000000003530436000000000023004b0000003b0000c13d000000000004004b000000020000006b000000c40000c13d000000400100043d00000020020000390000000002210436000000800300043d00000000003204350000004002100039000000000003004b0000008006000039000000520000613d00000000040000190000002006600039000000000506043300000000025204360000000104400039000000000034004b0000004c0000413d0000000002120049000000bc0000013d0000000001000416000000000001004b000000a50000c13d0000002001000039000001000010044300000120000004430000058b01000041000016250001042e0000058d0020009c0000008d0000613d0000058e0020009c000000a50000c13d000000240030008c000000a50000413d0000000002000416000000000002004b000000a50000c13d0000000401100370000000000101043b000005910010009c000000a50000213d162411df0000040f000000400200043d00000000001204350000058a0020009c0000058a02008041000000400120021000000592011001c7000016250001042e000000240030008c000000a50000413d0000000002000416000000000002004b000000a50000c13d0000000401100370000000000101043b000005910010009c000000a50000213d001500000001001d1624086a0000040f00000015010000291624087c0000040f0000002002000039000000400300043d001500000003001d0000000002230436162406d80000040f000000150200002900000000012100490000058a0010009c0000058a0100804100000060011002100000058a0020009c0000058a020080410000004002200210000000000121019f000016250001042e000000240030008c000000a50000413d0000000002000416000000000002004b000000a50000c13d0000000402100370000000000202043b000005930020009c000000a50000213d0000002304200039000000000034004b000000a50000813d0000000404200039000000000141034f000000000101043b001300000001001d000005930010009c000000a50000213d001200240020003d000000130100002900000005021002100000001201200029000000000031004b000000a70000a13d000000000100001900001626000104300000003f012000390000059403100197000005950030009c000004c70000213d0000008001300039000000400010043f0000001304000029000000800040043f000000000004004b000004b40000c13d00000020020000390000000002210436000000800300043d0000000000320435000000400510003900000005023002100000000004520019000d00000003001d000000000003004b000004cd0000c13d00000000021400490000058a0020009c0000058a0200804100000060022002100000058a0010009c0000058a010080410000004001100210000000000112019f000016250001042e0000000002000019000400000002001d0000000502200210000300000002001d00000001012000290000000201100367000000000101043b000700000001001d000005910010009c000000a50000213d0000000701000029000000000010043f0000059801000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000000a50000613d000000000101043b000000000101041a000c00000001001d0000059a01000041000000200010043f0000059b01000041000000000101041a000000400200043d001400000002001d0000000002120436000000000001004b000e00000002001d000000f20000613d0000059c030000410000000e020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b000000eb0000413d000000140120006a0000001f01100039000005b0011001970000001402100029000000000012004b00000000010000390000000101004039001100000002001d000005930020009c000004c70000213d0000000100100190000004c70000c13d0000001102000029000000400020043f0000059d01000041000000200010043f0000059e01000041000000000101041a0000000002120436000000000001004b000d00000002001d000001120000613d0000059f030000410000000d020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b0000010b0000413d000000110120006a0000001f01100039000005b0011001970000001102100029000000000012004b00000000010000390000000101004039001200000002001d000005930020009c000004c70000213d0000000100100190000004c70000c13d0000001203000029000000400030043f000005a001000041000000200010043f000005a102000041000000000102041a0000000003130436000000000020043f000000000001004b000500000003001d0000000002030019000001340000613d000005a20300004100000005020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b0000012d0000413d000000120120006a0000001f01100039000005b0021001970000001201200029000000000021004b00000000020000390000000102004039000005930010009c000004c70000213d0000000100200190000004c70000c13d000000400010043f00000012010000290000000001010433000600000001001d00000011010000290000000001010433000f00000001001d00000014010000290000000001010433000b00000001001d000000000001004b000002150000613d0000000006000019000001520000013d0000000c05000029000c00000005001d00000001066000390000000b0060006c000002150000813d00000014010000290000000001010433000000000061004b0000068a0000a13d00000005016002100000000e01100029001300000001001d00000000010104330000059101100197000000000010043f000005a301000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c70000801002000039001500000006001d1624161f0000040f00000015030000290000000100200190000000a50000613d000000000101043b00000014020000290000000002020433000000000032004b0000068a0000a13d0000000101100039000000000101041a001000000001001d000000130100002900000000010104330000059101100197000000000010043f000005a301000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f00000015060000290000000100200190000000a50000613d000000000101043b00000014020000290000000002020433000000000062004b0000068a0000a13d0000000201100039000000000501041a00000013010000290000000002010433000000400a00043d000005a40100004100000000001a04350000000401a000390000000703000029000000000031043500000000010004140000059102200197000000040020008c000001990000c13d0000000103000031000000200030008c00000020040000390000000004034019000001c70000013d000900000005001d0000058a00a0009c0000058a0300004100000000030a401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005a5011001c7000a0000000a001d1624161f0000040f0000000a0a00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000001b40000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000001b00000c13d0000001f07400190000001c10000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000069c0000613d000000150600002900000009050000290000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000005930010009c000004c70000213d0000000100200190000004c70000c13d000000400010043f000000200030008c000000a50000413d00000000010a0433000000000001004b0000014d0000613d000000ff0250018f000000020020008c0000000c050000290000066b0000813d000000000002004b000002100000613d000000100200002900000000032100a9000000000002004b000001e40000613d00000000022300d9000000000012004b000006960000c13d001000000003001d00000014010000290000000001010433000000000061004b0000068a0000a13d000000130100002900000000010104330000059101100197000000000010043f000005a301000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f00000015060000290000000100200190000000a50000613d000000000101043b000000000101041a0000004d0010008c0000000c050000290000001007000029000006960000213d000000000001004b00000001020000390000020c0000613d0000000a03000039000000010010019000000000043300a9000000010300603900000000022300a900000001011002720000000003040019000002030000c13d000000000002004b000006d20000613d00000000012700d9000000000051001a000006960000413d000002130000013d0000001001000029000000000051001a000006960000413d00000000055100190000014e0000013d0000000f0000006b000002b90000613d00000000050000190000021e0000013d0000000c04000029000c00000004001d00000001055000390000000f0050006c000002b90000813d00000011010000290000000001010433000000000051004b0000068a0000a13d00000005015002100000000d01100029001400000001001d00000000010104330000059101100197000000000010043f000005a801000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c70000801002000039001500000005001d1624161f0000040f00000015030000290000000100200190000000a50000613d000000000101043b00000011020000290000000002020433000000000032004b0000068a0000a13d000000000101041a001300000001001d000000140100002900000000010104330000059101100197000000000010043f000005a801000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f00000015050000290000000100200190000000a50000613d000000000101043b00000011020000290000000002020433000000000052004b0000068a0000a13d0000000101100039000000000601041a00000014010000290000000002010433000000400a00043d000005a40100004100000000001a04350000000401a000390000000703000029000000000031043500000000010004140000059102200197000000040020008c000002640000c13d0000000103000031000000200030008c00000020040000390000000004034019000002920000013d001000000006001d0000058a00a0009c0000058a0300004100000000030a401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005a5011001c700140000000a001d1624161f0000040f000000140a00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a00190000027f0000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b0000027b0000c13d0000001f074001900000028c0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000006a80000613d000000150500002900000010060000290000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000005930010009c000004c70000213d0000000100200190000004c70000c13d000000400010043f000000200030008c000000a50000413d00000000010a0433000000000001004b000002190000613d000000ff0260018f000000010020008c0000000c040000290000066b0000213d000000000002004b0000001303000029000002b00000613d000000000003004b000002b50000613d00000000023100a900000000033200d9000000000013004b000002b10000613d000006960000013d0000000002030019000000000042001a000006960000413d00000000044200190000021a0000013d0000000002000019000000000040001a000006960000413d000002b30000013d000000060000006b000004a80000613d0000000005000019000002c10000013d00000013050000290000000105500039000000060050006c000004a80000813d00000012010000290000000001010433000000000051004b0000068a0000a13d001300000005001d00000005015002100000000501100029001100000001001d00000000010104330000059101100197000000000010043f000005a901000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000000a50000613d000000000101043b000000000401041a000005930040009c000004c70000213d00000005024002100000003f022000390000059402200197000000400300043d0000000002230019001400000003001d000000000032004b00000000030000390000000103004039000005930020009c000004c70000213d0000000100300190000004c70000c13d000000400020043f0000001402000029000900000004001d0000000002420436000a00000002001d000000000010043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f0000000100200190000000a50000613d0000000906000029000000000006004b000000200500008a0000034a0000613d000000000701043b00000000080000190000001409000029000000000107041a000000010210019000000001041002700000007f0440618f0000001f0040008c00000000030000390000000103002039000000000032004b000006900000c13d000000400a00043d00000000034a0436000000000002004b0000032f0000613d000b00000003001d000d00000004001d000e0000000a001d000f00000009001d001000000008001d001500000007001d000000000070043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f0000000100200190000000a50000613d0000000d0b00002900000000000b004b000000090600002900000010080000290000000f09000029000003350000613d000000000201043b0000000001000019000000200500008a00000015070000290000000e0a0000290000000b0c00002900000000031c0019000000000402041a0000000000430435000000010220003900000020011000390000000000b1004b000003270000413d000003390000013d000005b1011001970000000000130435000000000004004b00000020010000390000000001006039000003390000013d0000000001000019000000200500008a00000015070000290000000e0a0000290000003f01100039000000000251016f0000000001a20019000000000021004b00000000020000390000000102004039000005930010009c000004c70000213d0000000100200190000004c70000c13d0000002009900039000000400010043f0000000000a9043500000001077000390000000108800039000000000068004b000002fe0000413d00000012010000290000000001010433000000130010006c0000068a0000a13d00000011010000290000000001010433000000400d00043d0000002402d0003900000040030000390000000000320435000005ab0200004100000000002d04350000000402d0003900000007030000290000000000320435000000140500002900000000020504330000004403d0003900000000002304350000006403d0003900000005042002100000000006340019000000000002004b0000037f0000613d0000000004000019000000200c00008a0000036d0000013d0000001f087000390000000008c8016f0000000007670019000000000007043500000000066800190000000104400039000000000024004b000003800000813d0000000007d60049000000640770008a00000000037304360000002005500039000000000705043300000000870704340000000006760436000000000007004b000003650000613d0000000009000019000000000a690019000000000b980019000000000b0b04330000000000ba04350000002009900039000000000079004b000003770000413d000003650000013d000000200c00008a00000591021001970000000001000414000000040020008c0000038a0000c13d000000030100036700000001030000310000000004c3017000000000024d0019000003a40000c13d000003aa0000013d0000000003d600490000058a0030009c0000058a0300804100000060033002100000058a00d0009c00150000000d001d0000058a0400004100000000040d40190000004004400210000000000343019f0000058a0010009c0000058a01008041000000c001100210000000000113019f1624161f0000040f00000060031002700001058a0030019d0000058a0330019700030000000103550000000100200190000006b40000613d000000200c00008a000000150d0000290000000004c3017000000000024d0019000003aa0000613d000000000501034f00000000060d0019000000005705043c0000000006760436000000000026004b000003a60000c13d0000001f05300190000003b70000613d000000000141034f0000000304500210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f013000390000000001c1016f0000000002d10019000000000012004b00000000010000390000000101004039000b00000002001d000005930020009c000004c70000213d0000000100100190000004c70000c13d0000000b01000029000000400010043f000005ac0030009c000000a50000213d000000200030008c000000a50000413d00000000010d0433000005930010009c000000a50000213d0000000002d300190000000001d100190000001f03100039000000000023004b0000000004000019000005ad04008041000005ad03300197000005ad05200197000000000653013f000000000053004b0000000003000019000005ad03004041000005ad0060009c000000000304c019000000000003004b000000a50000c13d0000000016010434000005930060009c000004c70000213d00000005036002100000003f0430003900000594044001970000000b04400029000005930040009c000004c70000213d000000400040043f0000000b040000290000000004640436000900000004001d0000000003130019000000000023004b000000a50000213d000000000031004b000003f50000813d0000000b02000029000000200220003900000000140104340000000000420435000000000031004b000003ee0000413d0000000b010000290000000006010433000000000006004b000002bd0000613d00000000070000190000001305000029000800000006001d000003fe0000013d0000000107700039000000080070006c000002be0000813d00000012010000290000000001010433000000000051004b0000068a0000a13d00000014010000290000000001010433000000000071004b0000068a0000a13d001500000007001d0000000502700210000e00000002001d0000000a02200029000000110100002900000000010104330000059101100197000f00000002001d0000000002020433001000000002001d000000000010043f000005ae01000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000000a50000613d000000400200043d000000000101043b000000010310003900000010010000290000000041010434000000000001004b0000042b0000613d000000000500001900000000062500190000000007540019000000000707043300000000007604350000002005500039000000000015004b000004240000413d000000000421001900000000003404350000058a0020009c0000058a02008041000000400220021000000020011000390000058a0010009c0000058a010080410000006001100210000000000121019f00000000020004140000058a0020009c0000058a02008041000000c002200210000000000112019f000005af011001c700008010020000391624161f0000040f0000000100200190000000a50000613d000000000101043b00000012020000290000000002020433000000130020006c00000015030000290000068a0000a13d00000014020000290000000002020433000000000032004b0000068a0000a13d000000000101041a000d00000001001d0000000f010000290000000001010433001000000001001d000000110100002900000000010104330000059101100197000000000010043f000005ae01000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000000a50000613d000000400200043d000000000101043b000000020310003900000010010000290000000041010434000000000001004b0000046c0000613d000000000500001900000000062500190000000007540019000000000707043300000000007604350000002005500039000000000015004b000004650000413d000000000421001900000000003404350000058a0020009c0000058a02008041000000400220021000000020011000390000058a0010009c0000058a010080410000006001100210000000000121019f00000000020004140000058a0020009c0000058a02008041000000c002200210000000000112019f000005af011001c700008010020000391624161f0000040f0000000100200190000000a50000613d000000000201043b0000000b0100002900000000010104330000001507000029000000000071004b00000013050000290000068a0000a13d0000000e0300002900000009013000290000000001010433000000000001004b000003fb0000613d000000000202041a000000ff0220018f000000010020008c0000000c0400002900000008060000290000066b0000213d000000000002004b0000000d030000290000049c0000613d000000000003004b000004a40000613d00000000023100a900000000033200d9000000000013004b0000049d0000613d000006960000013d0000000002030019000000000042001a000006960000413d000c00000042001d0000000107700039000000000067004b000003fe0000413d000002be0000013d0000000002000019000000000040001a000006960000413d0000049f0000013d000000800100043d000000040010006c0000068a0000a13d0000000301000029000000a0011000390000000c02000029000000000021043500000004020000290000000102200039000000020020006c000000c50000413d000000420000013d000005960030009c000004c70000213d000000600300003900000000040000190000006005100039000000400050043f00000040051000390000000000350435000000200510003900000000003504350000000000310435000000a00540003900000000001504350000002004400039000000000024004b000006710000813d000000400100043d000005970010009c000004b80000a13d000005a701000041000000000010043f0000004101000039000000040010043f000005a5010000410000162600010430000000a003000039001000000000001d000004d70000013d00000010030000290000000103300039001000000003001d0000000d0030006c0000000f050000290000000e03000029000000bb0000813d0000000002140049000000400220008a0000000005250436000f00000005001d0000000032030434000e00000003001d001100000002001d0000000025020434001400000002001d00000060020000390000000002240436000000600740003900000000060504330000000000670435000000800c4000390000000507600210000000000dc70019000000000006004b001500000002001d0000051f0000613d000000000e00001900000000074d0049000000800770008a000000000c7c04360000002005500039000000000705043300000000a9070434000005910990019700000000099d0436000000000a0a0433000000c0020000390000000000290435000000c00fd0003900000000b90a043400000000009f0435000000e00ad00039000000000009004b000005050000613d000000000f0000190000000003af00190000000002fb001900000000020204330000000000230435000000200ff0003900000000009f004b000004fe0000413d0000000002a9001900000000000204350000004002700039000000000b0204330000000100b0008c0000066b0000213d0000004002d000390000000000b20435000000600270003900000000020204330000006003d000390000000000230435000000800270003900000000020204330000008003d000390000000000230435000000a002d00039000000a003700039000000000303043300000000003204350000001f02900039000005b002200197000000000da20019000000010ee0003900000000006e004b000004ec0000413d0000001402000029000000000e02043300000000024d00490000001503000029000000000023043500000000030e043300000000003d0435000000050230021000000000022d0019000000200c200039001200000003001d000000000003004b000005a60000613d000000000f00001900000000030d0019000005350000013d000000130f000029000000010ff000390000001200f0006c000000140e0000290000001503000029000005a60000813d0000000002dc0049000000200220008a0000002003300039001500000003001d0000000000230435000000200ee0003900000000060e04330000000052060434000005910220019700000000022c04360000000005050433000001000300003900000000003204350000010002c00039000000009505043400000000005204350000012007c00039000000000005004b000005500000613d0000000002000019000000000a720019000000000b290019000000000b0b04330000000000ba04350000002002200039000000000052004b000005490000413d0000000002750019000000000002043500000040026000390000000002020433000000010020008c0000066b0000213d0000004009c000390000000000290435000000600260003900000000020204330000006009c000390000000000290435000000800260003900000000020204330000008009c000390000000000290435000000a0026000390000000002020433000000000002004b0000000002000039000000010200c039000000a009c0003900000000002904350000001f02500039000005b00220019700000000027200190000000005c20049000000c009c00039000000c0076000390000000007070433000000000059043500000000090704330000000005920436000000000009004b00140000000e001d0000057b0000613d00000000020000190000002007700039000000000a0704330000000005a504360000000102200039000000000092004b000005750000413d00130000000f001d000000e00260003900000000060204330000000002c50049000000e007c000390000000000270435000000000b0604330000000000b504350000000502b002100000000002250019000000200c20003900000000000b004b0000052f0000613d00000000070000190000000009050019000005930000013d0000000002ae001900000000000204350000001f02e00039000005b002200197000000000ca2001900000001077000390000000000b7004b0000052f0000813d00000000025c0049000000200220008a0000002009900039000000000029043500000020066000390000000002060433000000002e020434000000000aec043600000000000e004b0000058b0000613d000000000c0000190000000003ac0019000000000fc20019000000000f0f04330000000000f30435000000200cc000390000000000ec004b0000059e0000413d0000058b0000013d00000011020000290000004002200039000000000702043300000000024c004900000040034000390000000000230435000000000307043300000000003c0435000000050230021000000000022c00190000002004200039001100000003001d000000000003004b000004d00000613d000000000900001900000000030c0019000005bd0000013d000000140700002900000013090000290000000109900039000000110090006c0000001203000029000004d00000813d001300000009001d0000000002c40049000000200220008a0000002003300039001200000003001d00000000002304350000002007700039001400000007001d000000000b07043300000000530b0434000005910330019700000000033404360000000005050433000000e0020000390000000000230435000000e006400039000000007305043400000000003604350000010005400039000000000003004b000005da0000613d00000000090000190000000006590019000000000a970019000000000a0a04330000000000a604350000002009900039000000000039004b000005d30000413d000000000653001900000000000604350000001f03300039000005b003300197000000000a53001900150000000b001d0000004003b00039000000000b03043300000000034a00490000004005400039000000000035043500000000070b043300000000007a0435000000050370021000000000033a00190000002003300039000000000007004b0000060a0000613d000000000900001900000000050a0019000005f70000013d00000000023e001900000000000204350000001f02e00039000005b00220019700000000033200190000000109900039000000000079004b0000060a0000813d0000000006a30049000000200660008a00000020055000390000000000650435000000200bb0003900000000060b043300000000de0604340000000003e3043600000000000e004b000005ef0000613d0000000006000019000000000f36001900000000026d0019000000000202043300000000002f043500000020066000390000000000e6004b000006020000413d000005ef0000013d0000001502000029000000600220003900000000050204330000000002430049000000600640003900000000002604350000000007050433000000000073043500000005027002100000000002230019000000200b200039000000000007004b000006350000613d0000000009000019000000000a030019000006220000013d0000000002be001900000000000204350000001f02e00039000005b002200197000000000bb200190000000109900039000000000079004b000006350000813d00000000023b0049000000200220008a000000200aa0003900000000002a04350000002005500039000000000205043300000000de020434000000000beb043600000000000e004b0000061a0000613d00000000060000190000000002b60019000000000f6d0019000000000f0f04330000000000f2043500000020066000390000000000e6004b0000062d0000413d0000061a0000013d000000150a0000290000008002a00039000000000502043300000000024b004900000080034000390000000000230435000000000705043300000000037b0436000000000007004b000006480000613d000000000900001900000020055000390000000006050433000000010060008c0000066b0000213d00000000036304360000000109900039000000000079004b000006400000413d000000a002a0003900000000050204330000000002430049000000a006400039000000000026043500000000070504330000000003730436000000000007004b000006580000613d00000000090000190000002005500039000000000205043300000000032304360000000109900039000000000079004b000006520000413d000000c002a0003900000000020204330000000005430049000000c004400039000000000054043500000000050204330000000004530436000000000005004b000005b70000613d0000000003000019000000140700002900000013090000290000002002200039000000000602043300000000046404360000000103300039000000000053004b000006640000413d000005b90000013d000005a701000041000000000010043f0000002101000039000000040010043f000005a50100004100001626000104300000000003000019001500000003001d0000000502300210001400000002001d00000012012000290000000201100367000000000101043b000005910010009c000000a50000213d1624087c0000040f000000800200043d0000001503000029000000000032004b0000068a0000a13d0000001402000029000000a0022000390000000000120435000000800100043d000000000031004b0000068a0000a13d0000000103300039000000130030006c000006720000413d000000400100043d000000b10000013d000005a701000041000000000010043f0000003201000039000000040010043f000005a5010000410000162600010430000005a701000041000000000010043f0000002201000039000000040010043f000005a5010000410000162600010430000005a701000041000000000010043f0000001101000039000000040010043f000005a50100004100001626000104300000001f0530018f000005a606300198000000400200043d0000000004620019000006bf0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000006a30000c13d000006bf0000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000006bf0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000006af0000c13d000006bf0000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000006bf0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000006bb0000c13d000000000005004b000006cc0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500000060013002100000058a0020009c0000058a020080410000004002200210000000000112019f0000162600010430000005a701000041000000000010043f0000001201000039000000040010043f000005a50100004100001626000104300004000000000002000100000001001d0000000016010434000400000001001d00000060010000390000000007120436000000600120003900000000080604330000000000810435000300000002001d000000800920003900000005018002100000000005190019000000000008004b0000071b0000613d000000c00a000039000000000b000019000000030150006a000000800110008a00000000091904360000002006600039000000000c06043300000000210c04340000059101100197000000000115043600000000020204330000000000a10435000000c00e500039000000001d0204340000000000de0435000000e00e50003900000000000d004b000007010000613d000000000f0000190000000002ef00190000000004f1001900000000040404330000000000420435000000200ff000390000000000df004b000006fa0000413d0000000001ed001900000000000104350000004001c000390000000001010433000000020010008c000008640000813d000000400250003900000000001204350000006001c000390000000001010433000000600250003900000000001204350000008001c00039000000000101043300000080025000390000000000120435000000a001500039000000a002c00039000000000202043300000000002104350000001f01d00039000005b0011001970000000005e10019000000010bb0003900000000008b004b000006e90000413d00000004010000290000000002010433000000030150006a000000000017043500000000060204330000000000650435000000050160021000000000011500190000002004100039000200000006001d000000000006004b0000079f0000613d0000000009000019000000000a0500190000072f0000013d0000000109900039000000020090006c00000000020a0019000000040a0000290000079f0000813d0000000001540049000000200110008a000000200aa0003900000000001a04350000002002200039000000000c02043300000000710c0434000005910110019700000000011404360000000007070433000001000600003900000000006104350000010001400039000000008b0704340000000000b10435000001200d40003900000000000b004b000007490000613d00000000010000190000000007d10019000000000e180019000000000e0e04330000000000e7043500000020011000390000000000b1004b000007420000413d0000000001db001900000000000104350000004001c000390000000001010433000000010010008c000008640000213d000000400740003900000000001704350000006001c000390000000001010433000000600740003900000000001704350000008001c00039000000000101043300000080074000390000000000170435000000a001c000390000000001010433000000000001004b0000000001000039000000010100c039000000a00740003900000000001704350000001f01b00039000005b0011001970000000001d100190000000007410049000000c008400039000000c00bc00039000000000d0b04330000000000780435000000000e0d0433000000000be1043600000000000e004b00040000000a001d000007740000613d0000000001000019000000200dd0003900000000070d0433000000000b7b043600000001011000390000000000e1004b0000076e0000413d000000000a020019000000e001c00039000000000c01043300000000014b0049000000e0044000390000000000140435000000000d0c04330000000000db04350000000501d0021000000000011b0019000000200410003900000000000d004b0000072a0000613d000000000e000019000000000f0b00190000078c0000013d000000000148001900000000000104350000001f01800039000005b0011001970000000004410019000000010ee000390000000000de004b0000072a0000813d0000000001b40049000000200110008a000000200ff0003900000000001f0435000000200cc0003900000000010c043300000000180104340000000004840436000000000008004b000007840000613d000000000700001900000000024700190000000006710019000000000606043300000000006204350000002007700039000000000087004b000007970000413d000007840000013d000000010100002900000040011000390000000006010433000000030200002900000000012400490000004002200039000000000012043500000000020604330000000000240435000000050120021000000000011400190000002001100039000100000002001d000000000002004b000008630000613d00000000070000190000000008040019000007b70000013d0000000406000029000000030700002900000002080000290000000107700039000000010070006c000008630000813d000300000007001d0000000002410049000000200220008a0000002008800039000200000008001d00000000002804350000002006600039000400000006001d00000000090604330000000052090434000005910220019700000000022104360000000005050433000000e0060000390000000000620435000000e002100039000000006a0504340000000000a20435000001000b10003900000000000a004b000007d40000613d00000000020000190000000005b20019000000000c260019000000000c0c04330000000000c5043500000020022000390000000000a2004b000007cd0000413d0000000002ba001900000000000204350000001f02a00039000005b002200197000000000bb200190000004002900039000000000c02043300000000021b004900000040051000390000000000250435000000000d0c04330000000000db04350000000502d0021000000000022b0019000000200a20003900000000000d004b000008030000613d000000000e000019000000000f0b0019000007f00000013d0000000002a6001900000000000204350000001f02600039000005b002200197000000000aa20019000000010ee000390000000000de004b000008030000813d0000000002ba0049000000200220008a000000200ff0003900000000002f0435000000200cc0003900000000020c04330000000026020434000000000a6a0436000000000006004b000007e80000613d00000000050000190000000008a500190000000007520019000000000707043300000000007804350000002005500039000000000065004b000007fb0000413d000007e80000013d0000006002900039000000000b02043300000000021a004900000060051000390000000000250435000000000c0b04330000000000ca04350000000502c0021000000000022a0019000000200f20003900000000000c004b0000082d0000613d000000000d000019000000000e0a00190000081a0000013d0000000002f6001900000000000204350000001f02600039000005b002200197000000000ff20019000000010dd000390000000000cd004b0000082d0000813d0000000002af0049000000200220008a000000200ee0003900000000002e0435000000200bb0003900000000020b04330000000026020434000000000f6f0436000000000006004b000008120000613d00000000050000190000000007f500190000000008520019000000000808043300000000008704350000002005500039000000000065004b000008250000413d000008120000013d0000008002900039000000000b02043300000000021f004900000080051000390000000000250435000000000c0b0433000000000acf043600000000000c004b0000083f0000613d000000000d000019000000200bb0003900000000020b0433000000010020008c000008640000213d000000000a2a0436000000010dd000390000000000cd004b000008370000413d000000a002900039000000000b02043300000000021a0049000000a0051000390000000000250435000000000c0b0433000000000aca043600000000000c004b0000084f0000613d0000000002000019000000200bb0003900000000050b0433000000000a5a043600000001022000390000000000c2004b000008490000413d000000c002900039000000000902043300000000021a0049000000c0011000390000000000210435000000000b0904330000000001ba043600000000000b004b000007b10000613d000000000200001900000004060000290000000307000029000000020800002900000020099000390000000005090433000000000151043600000001022000390000000000b2004b0000085c0000413d000007b40000013d000000000001042d000005a701000041000000000010043f0000002101000039000000040010043f000005a5010000410000162600010430000000400100043d000005b20010009c000008760000813d0000006002100039000000400020043f000000400210003900000060030000390000000000320435000000200210003900000000003204350000000000310435000000000001042d000005a701000041000000000010043f0000004101000039000000040010043f000005a50100004100001626000104300016000000000002000300000001001d000000400100043d000005b20010009c0000115b0000813d0000006002100039000000400020043f000000400210003900000060030000390000000000320435000000200210003900000000003204350000000000310435000000400100043d000400000001001d000005970010009c0000115b0000213d00000004020000290000006001200039000000400010043f00000040032000390000006001000039000100000003001d00000000001304350000000002120436000200000002001d00000000001204350000059a01000041000000200010043f0000059b02000041000000000102041a000000400300043d001400000003001d0000000003130436000000000020043f000000000001004b000d00000003001d0000000002030019000008ad0000613d0000059c030000410000000d020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b000008a60000413d000000140120006a0000001f01100039000005b0011001970000001402100029000000000012004b00000000010000390000000101004039001600000002001d000005930020009c0000115b0000213d00000001001001900000115b0000c13d0000001603000029000000400030043f0000059d01000041000000200010043f0000059e02000041000000000102041a0000000003130436000000000020043f000000000001004b000a00000003001d0000000002030019000008cf0000613d0000059f030000410000000a020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b000008c80000413d000000160120006a0000001f01100039000005b0011001970000001602100029000000000012004b00000000010000390000000101004039001100000002001d000005930020009c0000115b0000213d00000001001001900000115b0000c13d0000001103000029000000400030043f000005a001000041000000200010043f000005a102000041000000000102041a0000000003130436000000000020043f000000000001004b000700000003001d0000000002030019000008f10000613d000005a20300004100000007020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b000008ea0000413d000000110120006a0000001f01100039000005b0011001970000001102100029000000000012004b00000000010000390000000101004039001500000002001d000005930020009c0000115b0000213d00000001001001900000115b0000c13d0000001501000029000000400010043f00000014010000290000000001010433000e00000001001d000005930010009c0000115b0000213d0000000e0100002900000005011002100000003f0210003900000594022001970000001502200029000005930020009c0000115b0000213d00000011030000290000000003030433000800000003001d00000016030000290000000003030433000b00000003001d000000400020043f00000015020000290000000e030000290000000002320436000f00000002001d000000000003004b00000a900000613d00000000020000190000006005000039000000400300043d000005b30030009c0000115b0000213d000000c004300039000000400040043f00000020043000390000000000540435000000a004300039000000000004043500000080043000390000000000040435000000600430003900000000000404350000004004300039000000000004043500000000000304350000000f0420002900000000003404350000002002200039000000000012004b0000091a0000413d0000000301000029000c05910010019b000000000500001900000014010000290000000001010433000000000051004b00000d7d0000a13d00000015010000290000000001010433000000000051004b00000d7d0000a13d00000005015002100000000d031000290000000f02100029001300000003001d00000000010304330000059101100197001200000002001d0000000002020433000000000012043500000014010000290000000001010433000000000051004b00000d7d0000a13d000000130100002900000000010104330000059101100197000000000010043f000005b401000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c70000801002000039001000000005001d1624161f0000040f00000010050000290000000100200190000011590000613d000000000101043b0000000101100039000000000201041a000000010320019000000001072002700000007f0770618f0000001f0070008c00000000040000390000000104002039000000000043004b000011610000c13d000000400600043d0000000004760436000000000003004b000009840000613d000500000004001d000900000007001d000600000006001d000000000010043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f00000010050000290000000100200190000011590000613d0000000907000029000000000007004b0000098a0000613d000000000201043b0000000001000019000000060600002900000005080000290000000003180019000000000402041a000000000043043500000001022000390000002001100039000000000071004b0000097c0000413d0000098c0000013d000005b1012001970000000000140435000000000007004b000000200100003900000000010060390000098c0000013d000000000100001900000006060000290000003f01100039000005b0021001970000000001620019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f00000015010000290000000001010433000000000051004b00000d7d0000a13d000000120100002900000000010104330000002001100039000000000061043500000014010000290000000001010433000000000051004b00000d7d0000a13d000000130100002900000000010104330000059101100197000000000010043f000005a301000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f00000010050000290000000100200190000011590000613d000000000101043b00000015020000290000000002020433000000000052004b00000d7d0000a13d0000000201100039000000000101041a000000ff0110018f000000020010008c000011670000813d000000120200002900000000020204330000004002200039000000000012043500000014010000290000000001010433000000000051004b00000d7d0000a13d00000013010000290000000002010433000000400a00043d000005b50100004100000000001a043500000000010004140000059102200197000000040020008c000009d30000c13d0000000103000031000000200030008c00000020040000390000000004034019000009ff0000013d0000058a00a0009c0000058a0300004100000000030a401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005b6011001c700090000000a001d1624161f0000040f000000090a00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000009ed0000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000009e90000c13d0000001f07400190000009fa0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000011a30000613d00000010050000290000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f000000200030008c000011590000413d00000000010a0433000000ff0010008c000011590000213d00000015020000290000000002020433000000000052004b00000d7d0000a13d000000120200002900000000020204330000006002200039000000000012043500000014010000290000000001010433000000000051004b00000d7d0000a13d000000130100002900000000010104330000059101100197000000000010043f000005a301000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f00000010050000290000000100200190000011590000613d00000015020000290000000002020433000000000052004b00000d7d0000a13d000000000101043b0000000101100039000000000101041a000000120200002900000000020204330000008002200039000000000012043500000014010000290000000001010433000000000051004b00000d7d0000a13d00000013010000290000000002010433000000400a00043d000005a40100004100000000001a04350000000401a000390000000c03000029000000000031043500000000010004140000059102200197000000040020008c00000a4b0000c13d0000000103000031000000200030008c0000002004000039000000000403401900000a770000013d0000058a00a0009c0000058a0300004100000000030a401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005a5011001c700130000000a001d1624161f0000040f000000130a00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a001900000a650000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b00000a610000c13d0000001f0740019000000a720000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000011af0000613d00000010050000290000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f000000200030008c000011590000413d00000015010000290000000001010433000000000051004b00000d7d0000a13d00000000010a043300000012020000290000000002020433000000a002200039000000000012043500000001055000390000000e0050006c000009320000413d0000000401000029000000150200002900000000002104350000000b01000029000005930010009c0000115b0000213d0000000b0100002900000005011002100000003f021000390000059402200197000000400900043d0000000002290019000000000092004b00000000030000390000000103004039000005930020009c0000115b0000213d00000001003001900000115b0000c13d000000400020043f0000000b020000290000000003290436000c00000003001d000000000002004b00000d830000613d00000000020000190000006005000039000000400300043d000005b70030009c0000115b0000213d0000010004300039000000400040043f000000e0043000390000000000540435000000c004300039000000000054043500000020043000390000000000540435000000a004300039000000000004043500000080043000390000000000040435000000600430003900000000000404350000004004300039000000000004043500000000000304350000000c0420002900000000003404350000002002200039000000000012004b00000aab0000413d0000000301000029000f05910010019b000000000a000019001000000009001d00000acc0000013d000000010aa000390000000b00a0006c00000d830000813d000000160100002900000000010104330000000000a1004b00000d7d0000a13d00000000010904330000000000a1004b00000d7d0000a13d0000000501a002100000000a031000290000000c04100029001500000003001d0000000001030433000005910110019700000000020404330000000000120435000000160100002900000000010104330000000000a1004b00000d7d0000a13d000000150100002900000000010104330000059101100197000000000010043f000005b401000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c7000080100200003900130000000a001d001200000004001d1624161f0000040f0000001207000029000000130600002900000010050000290000000100200190000011590000613d000000000101043b0000000101100039000000000201041a000000010320019000000001092002700000007f0990618f0000001f0090008c00000000040000390000000104002039000000000442013f0000000100400190000011610000c13d000000400800043d0000000004980436000000000003004b00000b220000613d000d00000004001d000e00000009001d001400000008001d000000000010043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f0000001207000029000000130600002900000010050000290000000100200190000011590000613d0000000e09000029000000000009004b00000b280000613d000000000201043b000000000100001900000014080000290000000d0a00002900000000031a0019000000000402041a000000000043043500000001022000390000002001100039000000000091004b00000b1a0000413d00000b2a0000013d000005b1012001970000000000140435000000000009004b0000002001000039000000000100603900000b2a0000013d000000000100001900000014080000290000003f01100039000005b0021001970000000001820019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f0000000001050433000000000061004b00000d7d0000a13d00000000010704330000002001100039000000000081043500000016010000290000000001010433000000000061004b00000d7d0000a13d000000150100002900000000010104330000059101100197000000000010043f000005a801000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000001205000029000000130400002900000010030000290000000100200190000011590000613d000000000101043b0000000002030433000000000042004b00000d7d0000a13d0000000101100039000000000101041a000000ff0110018f000000010010008c000011670000213d00000000020504330000004002200039000000000012043500000016010000290000000001010433000000000041004b00000d7d0000a13d000000150100002900000000010104330000059101100197000000000010043f000005a801000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f000000120b000029000000130a00002900000010090000290000000100200190000011590000613d00000000020904330000000000a2004b00000d7d0000a13d000000000101043b000000000101041a00000000020b043300000060022000390000000000120435000000160100002900000000010104330000000000a1004b00000d7d0000a13d00000015010000290000000002010433000000400c00043d000005a40100004100000000001c04350000000401c000390000000f03000029000000000031043500000000010004140000059102200197000000040020008c00000b900000c13d0000000103000031000000200030008c0000002004000039000000000403401900000bbe0000013d0000058a00c0009c0000058a0300004100000000030c401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005a5011001c700140000000c001d1624161f0000040f000000140c00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056c001900000baa0000613d000000000701034f00000000080c0019000000007907043c0000000008980436000000000058004b00000ba60000c13d0000001f0740019000000bb70000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000001009000029000000130a000029000000120b000029000011bb0000613d0000001f01400039000000600110018f0000000002c10019000000000012004b00000000040000390000000104004039000005930020009c0000115b0000213d00000001004001900000115b0000c13d000000400020043f000000200030008c000011590000413d00000000020904330000000000a2004b00000d7d0000a13d00000000020c043300000000040b043300000080044000390000000000240435000000160200002900000000020204330000000000a2004b00000d7d0000a13d00000015020000290000000002020433000000400c00043d000005b80400004100000000004c04350000000404c00039000005b905000041000000000054043500000000040004140000059102200197000000040020008c00000c120000613d0000058a00c0009c0000058a0100004100000000010c401900000040011002100000058a0040009c0000058a04008041000000c003400210000000000113019f000005a5011001c700140000000c001d1624161f0000040f000000140c00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056c001900000bfc0000613d000000000701034f00000000080c0019000000007907043c0000000008980436000000000058004b00000bf80000c13d0000001f0740019000000c090000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000001009000029000000130a000029000000120b000029000011c70000613d0000001f01400039000000600110018f0000000002c10019000000000012004b00000000010000390000000101004039000005930020009c0000115b0000213d00000001001001900000115b0000c13d000000400020043f000000200030008c000011590000413d00000000010c0433000000000001004b0000000002000039000000010200c039000000000021004b000011590000c13d00000000020904330000000000a2004b00000d7d0000a13d00000000020b0433000000a002200039000000000012043500000000010904330000000000a1004b00000d7d0000a13d00000000010b043300000080021000390000000004020433000000000004004b00000ac90000613d000000a0011000390000000001010433000000000001004b00000ac90000613d000005930040009c0000115b0000213d00000005024002100000003f012000390000059405100197000000400100043d0000000005510019000000000015004b00000000060000390000000106004039000005930050009c0000115b0000213d00000001006001900000115b0000c13d000000400050043f0000000004410436000000000002004b00000c4e0000613d000000000524001900000000060000310000000206600367000000006706043c0000000004740436000000000054004b00000c4a0000c13d0000001f0020019000000000020904330000000000a2004b00000d7d0000a13d00000000020b0433000000c002200039000000000012043500000000010904330000000000a1004b00000d7d0000a13d00000000010b043300000080011000390000000004010433000005930040009c0000115b0000213d00000005024002100000003f012000390000059405100197000000400100043d0000000005510019000000000015004b00000000060000390000000106004039000005930050009c0000115b0000213d00000001006001900000115b0000c13d000000400050043f0000000005410436000000000004004b000000600700003900000c740000613d0000000004000019000000000645001900000000007604350000002004400039000000000024004b00000c6f0000413d00000000020904330000000000a2004b00000d7d0000a13d00000000020b0433000000e002200039000000000012043500000000010904330000000000a1004b00000d7d0000a13d000000000c00001900000000010b04330000008001100039000000000101043300000000001c004b00000ac90000813d000000160100002900000000010104330000000000a1004b00000d7d0000a13d00000015010000290000000002010433000000400d00043d0000002401d000390000000000c10435000005ba0100004100000000001d04350000000401d000390000000f04000029000000000041043500000000010004140000059102200197000000040020008c00140000000c001d00000c9a0000c13d000000200030008c0000002004000039000000000403401900000cc90000013d0000058a00d0009c0000058a0300004100000000030d401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005bb011001c7000e0000000d001d1624161f0000040f0000000e0d00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056d001900000cb40000613d000000000701034f00000000080d0019000000007907043c0000000008980436000000000058004b00000cb00000c13d0000001f0740019000000cc10000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000001009000029000000130a000029000000120b000029000000140c000029000011790000613d0000001f01400039000000600210018f0000000001d20019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f000000200030008c000011590000413d00000000010904330000000000a1004b00000d7d0000a13d00000000010b0433000000c001100039000000000101043300000000020104330000000000c2004b00000d7d0000a13d00000000020d04330000000504c00210000000200d40003900000000011d00190000000000210435000000160100002900000000010104330000000000a1004b00000d7d0000a13d00000000010904330000000000a1004b00000d7d0000a13d00000000010b0433000000c001100039000000000101043300000000020104330000000000c2004b00000d7d0000a13d00000015020000290000000002020433000005910220019700000000011d00190000000001010433000000400800043d000005bc040000410000000000480435000000040480003900000000001404350000000001000414000000040020008c00000d000000c13d000000030100036700000d180000013d000e0000000d001d0000058a0080009c000d00000008001d0000058a03000041000000000308401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005a5011001c71624161f0000040f00000060031002700001058a0030019d0000058a0330019700030000000103550000000100200190000011850000613d0000001009000029000000130a000029000000120b000029000000140c0000290000000e0d0000290000000d08000029000005b004300198000000000248001900000d210000613d000000000501034f0000000006080019000000005705043c0000000006760436000000000026004b00000d1d0000c13d0000001f0530019000000d2e0000613d000000000141034f0000000304500210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f01300039000005b0021001970000000001820019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f000005ac0030009c000011590000213d000000200030008c000011590000413d0000000002080433000005930020009c000011590000213d000000000583001900000000028200190000001f04200039000000000054004b0000000006000019000005ad06008041000005ad04400197000005ad07500197000000000874013f000000000074004b0000000004000019000005ad04004041000005ad0080009c000000000406c019000000000004004b000011590000c13d0000000042020434000005930020009c0000115b0000213d0000001f06200039000005b0066001970000003f06600039000005b0066001970000000006160019000005930060009c0000115b0000213d000000400060043f00000000062104360000000007420019000000000057004b000011590000213d000000000002004b00000d690000613d000000000500001900000000076500190000000008450019000000000808043300000000008704350000002005500039000000000025004b00000d620000413d0000000002620019000000000002043500000000020904330000000000a2004b00000d7d0000a13d00000000020b0433000000e002200039000000000202043300000000040204330000000000c4004b00000d7d0000a13d00000000042d0019000000000014043500000000010204330000000000c1004b00000d7d0000a13d000000010cc0003900000000010904330000000000a1004b00000c7e0000213d000005a701000041000000000010043f0000003201000039000000040010043f000005a5010000410000162600010430000000020100002900000000009104350000000801000029000005930010009c0000115b0000213d000000080100002900000005011002100000003f021000390000059402200197000000400300043d0000000002230019001600000003001d000000000032004b00000000030000390000000103004039000005930020009c0000115b0000213d00000001003001900000115b0000c13d000000400020043f000000080200002900000016030000290000000003230436000900000003001d000000000002004b000011540000613d00000000020000190000006005000039000000400300043d000005960030009c0000115b0000213d000000e004300039000000400040043f000000c0043000390000000000540435000000a0043000390000000000540435000000800430003900000000005404350000006004300039000000000054043500000040043000390000000000540435000000200430003900000000005404350000000000030435000000090420002900000000003404350000002002200039000000000012004b00000d9f0000413d0000000301000029000605910010019b000000000500001900000dbd0000013d0000000105500039000000080050006c000011540000813d00000011010000290000000001010433000000000051004b00000d7d0000a13d00000016010000290000000001010433000000000051004b00000d7d0000a13d000000050150021000000007031000290000000902100029001000000003001d00000000010304330000059101100197001500000002001d0000000002020433000000000012043500000011010000290000000001010433000000000051004b00000d7d0000a13d001200000005001d000000100100002900000000010104330000059101100197000000000010043f000005b401000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000011590000613d000000000101043b0000000101100039000000000201041a000000010320019000000001062002700000007f0660618f0000001f0060008c00000000040000390000000104002039000000000442013f0000000100400190000011610000c13d000000400500043d0000000004650436000000000003004b00000e0e0000613d000f00000004001d001300000006001d001400000005001d000000000010043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f0000000100200190000011590000613d0000001306000029000000000006004b00000e140000613d000000000201043b000000000100001900000014050000290000000f070000290000000003170019000000000402041a000000000043043500000001022000390000002001100039000000000061004b00000e060000413d00000e160000013d000005b1012001970000000000140435000000000006004b0000002001000039000000000100603900000e160000013d000000000100001900000014050000290000003f01100039000005b0021001970000000001520019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f000000160100002900000000010104330000001202000029000000000021004b00000d7d0000a13d000000150100002900000000010104330000002001100039000000000051043500000011010000290000000001010433000000000021004b00000d7d0000a13d000000100100002900000000010104330000059101100197000000000010043f000005a901000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000011590000613d000000000101043b000000000401041a000005930040009c0000115b0000213d00000005024002100000003f022000390000059402200197000000400300043d0000000002230019000a00000003001d000000000032004b00000000030000390000000103004039000005930020009c0000115b0000213d00000001003001900000115b0000c13d000000400020043f0000000a02000029000b00000004001d0000000000420435000000000010043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f0000000100200190000011590000613d0000000b05000029000000000005004b00000ead0000613d000000000601043b00000000070000190000000a08000029000000000106041a000000010210019000000001041002700000007f0440618f0000001f0040008c00000000030000390000000103002039000000000331013f0000000100300190000011610000c13d000000400900043d0000000003490436000000000002004b00000e930000613d000c00000003001d000d00000004001d000e00000009001d000f00000008001d001300000007001d001400000006001d000000000060043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f0000000100200190000011590000613d0000000d0a00002900000000000a004b0000000b0500002900000013070000290000000f0800002900000e990000613d000000000201043b000000000100001900000014060000290000000e090000290000000c0b00002900000000031b0019000000000402041a0000000000430435000000010220003900000020011000390000000000a1004b00000e8b0000413d00000e9c0000013d000005b1011001970000000000130435000000000004004b0000002001000039000000000100603900000e9c0000013d000000000100001900000014060000290000000e090000290000003f01100039000005b0021001970000000001920019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d0000002008800039000000400010043f000000000098043500000001066000390000000107700039000000000057004b00000e620000413d000000160100002900000000010104330000001202000029000000000021004b00000d7d0000a13d0000001501000029000000000101043300000040011000390000000a03000029000000000031043500000011010000290000000001010433000000000021004b00000d7d0000a13d00000016010000290000000001010433000000000021004b00000d7d0000a13d000000100100002900000000010104330000001502000029000000000202043300000040022000390000000002020433000000400c00043d0000002403c0003900000040040000390000000000430435000005ab0300004100000000003c04350000000403c00039000000060400002900000000004304350000004404c00039000000000302043300000000003404350000006404c0003900000005053002100000000006450019000000000003004b00000ef20000613d000000000500001900000ee00000013d0000001f08700039000005b0088001970000000007670019000000000007043500000000066800190000000105500039000000000035004b00000ef20000813d0000000007c60049000000640770008a00000000047404360000002002200039000000000702043300000000870704340000000006760436000000000007004b00000ed80000613d0000000009000019000000000a690019000000000b980019000000000b0b04330000000000ba04350000002009900039000000000079004b00000eea0000413d00000ed80000013d00000591021001970000000001000414000000040020008c00000ef90000c13d0000000301000367000000010300003100000f0f0000013d0000000003c600490000058a0030009c0000058a0300804100000060033002100000058a00c0009c00140000000c001d0000058a0400004100000000040c40190000004004400210000000000343019f0000058a0010009c0000058a01008041000000c001100210000000000113019f1624161f0000040f00000060031002700001058a0030019d0000058a0330019700030000000103550000000100200190000011d30000613d000000140c000029000005b00430019800000000024c001900000f180000613d000000000501034f00000000060c0019000000005705043c0000000006760436000000000026004b00000f140000c13d0000001f0530019000000f250000613d000000000141034f0000000304500210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f01300039000005b0021001970000000001c20019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f000005ac0030009c000011590000213d000000200030008c000011590000413d00000000020c0433000005930020009c000011590000213d0000000003c300190000000002c200190000001f04200039000000000034004b0000000005000019000005ad05008041000005ad04400197000005ad06300197000000000764013f000000000064004b0000000004000019000005ad04004041000005ad0070009c000000000405c019000000000004004b000011590000c13d0000000024020434000005930040009c0000115b0000213d00000005054002100000003f0650003900000594066001970000000006160019000005930060009c0000115b0000213d000000400060043f00000000004104350000000004250019000000000034004b000011590000213d000000000042004b00000f5d0000813d0000000003010019000000200330003900000000250204340000000000530435000000000042004b00000f580000413d000000160200002900000000020204330000001203000029000000000032004b00000d7d0000a13d00000015020000290000000002020433000000c002200039000000000012043500000016010000290000000001010433000000000031004b00000d7d0000a13d00000015010000290000000001010433000000c00110003900000000010104330000000001010433000e00000001001d000005930010009c0000115b0000213d0000000e0100002900000005011002100000003f021000390000059402200197000000400300043d0000000004230019000000000034004b00000000050000390000000105004039000005930040009c0000115b0000213d00000001005001900000115b0000c13d000000400040043f0000000e050000290000000004530436000000000005004b000000600700003900000f8b0000613d0000000005000019000000000654001900000000007604350000002005500039000000000015004b00000f860000413d00000016040000290000000004040433000000120040006c00000d7d0000a13d0000001504000029000000000404043300000060044000390000000000340435000000400400043d0000000003240019000000000043004b00000000050000390000000105004039000005930030009c0000115b0000213d00000001005001900000115b0000c13d000000400030043f0000000e03000029000000000534043600000000030000310000000203300367000000000001004b00000fa90000613d0000000006150019000000000703034f000000007807043c0000000005850436000000000065004b00000fa50000c13d0000001f0510019000000016060000290000000006060433000000120060006c00000d7d0000a13d0000001506000029000000000606043300000080066000390000000000460435000000400400043d0000000002240019000000000042004b00000000060000390000000106004039000005930020009c0000115b0000213d00000001006001900000115b0000c13d000000400020043f0000000e020000290000000002240436000000000001004b00000fc50000613d0000000001120019000000003603043c0000000002620436000000000012004b00000fc10000c13d000000000005004b000000120500002900000016010000290000000001010433000000000051004b00000d7d0000a13d00000015010000290000000001010433000000a00110003900000000004104350000000e0000006b00000dba0000613d000000000400001900000011010000290000000001010433000000000051004b00000d7d0000a13d00000016010000290000000001010433000000000051004b00000d7d0000a13d00000015010000290000000001010433000000400110003900000000010104330000000002010433000000000042004b00000d7d0000a13d00000010020000290000000009020433001300000004001d0000000502400210001400200020003d00000014011000290000000003010433000000400100043d0000002002100039000000200400003900000000004204350000000043030434000000400510003900000000003504350000006005100039000000000003004b00000ffa0000613d000000000600001900000000075600190000000008640019000000000808043300000000008704350000002006600039000000000036004b00000ff30000413d000000000453001900000000000404350000001f03300039000005b003300197000000400430003900000000004104350000007f03300039000005b0043001970000000003140019000000000043004b00000000040000390000000104004039000005930030009c0000115b0000213d00000001004001900000115b0000c13d000f00000009001d000000400030043f0000058a0020009c0000058a02008041000000400220021000000000010104330000058a0010009c0000058a010080410000006001100210000000000121019f00000000020004140000058a0020009c0000058a02008041000000c002200210000000000112019f000005af011001c700008010020000391624161f0000040f0000000100200190000011590000613d0000000f020000290000059102200197000000000101043b000000400800043d000005bd030000410000000000380435000000040380003900000000001304350000000001000414000000040020008c0000102c0000c13d000000030100036700000001030000310000103e0000013d0000058a0080009c000f00000008001d0000058a03000041000000000308401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005a5011001c71624161f0000040f00000060031002700001058a0030019d0000058a03300197000300000001035500000001002001900000116d0000613d0000000f08000029000005b0043001980000000002480019000010470000613d000000000501034f0000000006080019000000005705043c0000000006760436000000000026004b000010430000c13d0000001f05300190000010540000613d000000000141034f0000000304500210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f01300039000005b0021001970000000001820019000000000021004b00000000020000390000000102004039000005930010009c0000115b0000213d00000001002001900000115b0000c13d000000400010043f000005ac0030009c000011590000213d000000200030008c000011590000413d0000000002080433000005930020009c000011590000213d000000000483001900000000028200190000001f03200039000000000043004b0000000005000019000005ad05008041000005ad03300197000005ad06400197000000000763013f000000000063004b0000000003000019000005ad03004041000005ad0070009c000000000305c019000000000003004b000011590000c13d0000000032020434000005930020009c0000115b0000213d0000001f05200039000005b0055001970000003f05500039000005b0055001970000000005150019000005930050009c0000115b0000213d000000400050043f00000000052104360000000006320019000000000046004b000011590000213d000000000002004b0000108f0000613d000000000400001900000000065400190000000007340019000000000707043300000000007604350000002004400039000000000024004b000010880000413d00000000025200190000000000020435000000160200002900000000020204330000001204000029000000000042004b000000130500002900000d7d0000a13d00000015020000290000000002020433000000600220003900000000020204330000000003020433000000000053004b00000d7d0000a13d000000140320002900000000001304350000000001020433000000000051004b00000d7d0000a13d00000011010000290000000001010433000000000041004b00000d7d0000a13d00000016010000290000000001010433000000000041004b00000d7d0000a13d00000015010000290000000001010433000000400110003900000000010104330000000002010433000000000052004b00000d7d0000a13d00000010020000290000000002020433000005910220019700000014011000290000000001010433000f00000001001d000000000020043f000005ae01000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000011590000613d000000400200043d000000000101043b00000002031000390000000f010000290000000041010434000000000001004b000010d30000613d000000000500001900000000062500190000000007540019000000000707043300000000007604350000002005500039000000000015004b000010cc0000413d000000000421001900000000003404350000058a0020009c0000058a02008041000000400220021000000020011000390000058a0010009c0000058a010080410000006001100210000000000121019f00000000020004140000058a0020009c0000058a02008041000000c002200210000000000112019f000005af011001c700008010020000391624161f0000040f0000000100200190000011590000613d000000000101043b000000160200002900000000020204330000001204000029000000000042004b000000130500002900000d7d0000a13d00000015020000290000000002020433000000800220003900000000020204330000000003020433000000000053004b00000d7d0000a13d000000000101041a000000ff0110018f000000010010008c000011670000213d0000001402200029000000000012043500000011010000290000000001010433000000000041004b00000d7d0000a13d00000016010000290000000001010433000000000041004b00000d7d0000a13d00000015010000290000000001010433000000400110003900000000010104330000000002010433000000000052004b00000d7d0000a13d00000010020000290000000002020433000005910220019700000014011000290000000001010433000f00000001001d000000000020043f000005ae01000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000011590000613d000000400200043d000000000101043b00000001031000390000000f010000290000000041010434000000000001004b0000112b0000613d000000000500001900000000062500190000000007540019000000000707043300000000007604350000002005500039000000000015004b000011240000413d000000000421001900000000003404350000058a0020009c0000058a02008041000000400220021000000020011000390000058a0010009c0000058a010080410000006001100210000000000121019f00000000020004140000058a0020009c0000058a02008041000000c002200210000000000112019f000005af011001c700008010020000391624161f0000040f0000000100200190000011590000613d000000000101043b000000160200002900000000020204330000001205000029000000000052004b000000130400002900000d7d0000a13d00000015020000290000000002020433000000a00220003900000000020204330000000003020433000000000043004b00000d7d0000a13d000000000101041a0000001402200029000000000012043500000001044000390000000e0040006c00000fd20000413d00000dba0000013d0000000101000029000000160200002900000000002104350000000401000029000000000001042d00000000010000190000162600010430000005a701000041000000000010043f0000004101000039000000040010043f000005a5010000410000162600010430000005a701000041000000000010043f0000002201000039000000040010043f000005a5010000410000162600010430000005a701000041000000000010043f0000002101000039000000040010043f000005a50100004100001626000104300000001f0530018f000005a606300198000000400200043d0000000004620019000011900000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011740000c13d000011900000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000011900000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011800000c13d000011900000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000011900000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000118c0000c13d000000000005004b0000119d0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500000060013002100000058a0020009c0000058a020080410000004002200210000000000121019f00001626000104300000001f0530018f000005a606300198000000400200043d0000000004620019000011900000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011aa0000c13d000011900000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000011900000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011b60000c13d000011900000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000011900000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011c20000c13d000011900000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000011900000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011ce0000c13d000011900000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000011900000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000011da0000c13d000011900000013d00110000000000020000059101100197000300000001001d000000000010043f0000059801000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000015cf0000613d000000000101043b000000000601041a0000059a01000041000000200010043f0000059b02000041000000000102041a000000400300043d000f00000003001d0000000003130436000000000020043f000000000001004b000900000003001d0000000002030019000012060000613d0000059c0300004100000009020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b000011ff0000413d0000000f0120006a0000001f01100039000005b0011001970000000f02100029000000000012004b00000000010000390000000101004039000c00000002001d000005930020009c000015d10000213d0000000100100190000015d10000c13d0000000c03000029000000400030043f0000059d01000041000000200010043f0000059e02000041000000000102041a0000000003130436000000000020043f000000000001004b000800000003001d0000000002030019000012280000613d0000059f0300004100000008020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b000012210000413d0000000c0120006a0000001f01100039000005b0011001970000000c02100029000000000012004b00000000010000390000000101004039000d00000002001d000005930020009c000015d10000213d0000000100100190000015d10000c13d0000000d03000029000000400030043f000005a001000041000000200010043f000005a102000041000000000102041a0000000003130436000000000020043f000000000001004b000100000003001d00000000020300190000124a0000613d000005a20300004100000001020000290000000004000019000000000503041a0000059105500197000000000252043600000001033000390000000104400039000000000014004b000012430000413d0000000d0120006a0000001f01100039000005b0021001970000000d01200029000000000021004b00000000020000390000000102004039000005930010009c000015d10000213d0000000100200190000015d10000c13d000000400010043f0000000d010000290000000001010433000200000001001d0000000c010000290000000001010433000a00000001001d0000000f010000290000000001010433000700000001001d000000000001004b0000132c0000613d00000000070000190000000001060019000012680000013d00000010010000290000000107700039000000070070006c0000132d0000813d001000000001001d0000000f010000290000000001010433000000000071004b000015c90000a13d00000005017002100000000901100029000e00000001001d00000000010104330000059101100197000000000010043f000005a301000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c70000801002000039001100000007001d1624161f0000040f00000011030000290000000100200190000015cf0000613d000000000101043b0000000f020000290000000002020433000000000032004b000015c90000a13d0000000101100039000000000101041a000b00000001001d0000000e0100002900000000010104330000059101100197000000000010043f000005a301000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f00000011070000290000000100200190000015cf0000613d000000000101043b0000000f020000290000000002020433000000000072004b000015c90000a13d0000000201100039000000000501041a0000000e010000290000000002010433000000400a00043d000005a40100004100000000001a04350000000401a000390000000303000029000000000031043500000000010004140000059102200197000000040020008c000012b00000c13d0000000103000031000000200030008c00000020040000390000000004034019000012de0000013d000500000005001d0000058a00a0009c0000058a0300004100000000030a401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005a5011001c700060000000a001d1624161f0000040f000000060a00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000012cb0000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000012c70000c13d0000001f07400190000012d80000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000015e30000613d000000110700002900000005050000290000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000005930010009c000015d10000213d0000000100200190000015d10000c13d000000400010043f000000200030008c000015cf0000413d00000000030a0433000000000003004b000012640000613d000000ff0250018f000000020020008c0000001001000029000015dd0000813d000000000002004b000013270000613d0000000b0100002900000000041300a9000000000001004b000012fb0000613d00000000021400d9000000000032004b000015c20000c13d000b00000004001d0000000f010000290000000001010433000000000071004b000015c90000a13d0000000e0100002900000000010104330000059101100197000000000010043f000005a301000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f00000011070000290000000100200190000015cf0000613d000000000101043b000000000501041a0000004d0050008c00000010010000290000000b06000029000015c20000213d000000000005004b0000000102000039000013230000613d0000000a03000039000000010050019000000000043300a9000000010300603900000000022300a9000000010550027200000000030400190000131a0000c13d000000000002004b000016190000613d00000000022600d9000000000012001a000015c20000413d0000132a0000013d0000000b02000029000000000012001a000015c20000413d0000000001120019000012650000013d00000000010600190000000a0000006b000013d10000613d0000000005000019000013350000013d000000100100002900000001055000390000000a0050006c000013d10000813d001000000001001d0000000c010000290000000001010433000000000051004b000015c90000a13d00000005015002100000000801100029000f00000001001d00000000010104330000059101100197000000000010043f000005a801000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c70000801002000039001100000005001d1624161f0000040f00000011030000290000000100200190000015cf0000613d000000000101043b0000000c020000290000000002020433000000000032004b000015c90000a13d000000000101041a000e00000001001d0000000f0100002900000000010104330000059101100197000000000010043f000005a801000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f00000011050000290000000100200190000015cf0000613d000000000101043b0000000c020000290000000002020433000000000052004b000015c90000a13d0000000101100039000000000601041a0000000f010000290000000002010433000000400a00043d000005a40100004100000000001a04350000000401a000390000000303000029000000000031043500000000010004140000059102200197000000040020008c0000137c0000c13d0000000103000031000000200030008c00000020040000390000000004034019000013aa0000013d000b00000006001d0000058a00a0009c0000058a0300004100000000030a401900000040033002100000058a0010009c0000058a01008041000000c001100210000000000131019f000005a5011001c7000f0000000a001d1624161f0000040f0000000f0a00002900000060031002700000058a03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000013970000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000013930000c13d0000001f07400190000013a40000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000015ef0000613d00000011050000290000000b060000290000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000005930010009c000015d10000213d0000000100200190000015d10000c13d000000400010043f000000200030008c000015cf0000413d00000000040a0433000000000004004b000013310000613d000000ff0260018f000000010020008c0000001001000029000015dd0000213d000000000002004b0000000e03000029000013c80000613d000000000003004b000013cd0000613d00000000023400a900000000033200d9000000000043004b000013c90000613d000015c20000013d0000000002030019000000000012001a000015c20000413d0000000001120019000013320000013d0000000002000019000000000010001a000015c20000413d000013cb0000013d000000020000006b000015c80000613d0000000005000019000013da0000013d00000010010000290000000e050000290000000105500039000000020050006c000015c80000813d001000000001001d0000000d010000290000000001010433000000000051004b000015c90000a13d000e00000005001d00000005015002100000000101100029000c00000001001d00000000010104330000059101100197000000000010043f000005a901000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000015cf0000613d000000000101043b000000000401041a000005930040009c000015d10000213d00000005024002100000003f022000390000059402200197000000400300043d0000000002230019000f00000003001d000000000032004b00000000030000390000000103004039000005930020009c000015d10000213d0000000100300190000015d10000c13d000000400020043f0000000f02000029000500000004001d0000000002420436000600000002001d000000000010043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f0000000100200190000015cf0000613d0000000506000029000000000006004b000000200500008a000014640000613d000000000701043b00000000080000190000000f09000029000000000107041a000000010210019000000001041002700000007f0440618f0000001f0040008c00000000030000390000000103002039000000000032004b000015d70000c13d000000400a00043d00000000034a0436000000000002004b000014490000613d000700000003001d000800000004001d00090000000a001d000a00000009001d000b00000008001d001100000007001d000000000070043f00000000010004140000058a0010009c0000058a01008041000000c001100210000005aa011001c700008010020000391624161f0000040f0000000100200190000015cf0000613d000000080b00002900000000000b004b00000005060000290000000b080000290000000a090000290000144f0000613d000000000201043b0000000001000019000000200500008a0000001107000029000000090a000029000000070c00002900000000031c0019000000000402041a0000000000430435000000010220003900000020011000390000000000b1004b000014410000413d000014530000013d000005b1011001970000000000130435000000000004004b00000020010000390000000001006039000014530000013d0000000001000019000000200500008a0000001107000029000000090a0000290000003f01100039000000000251016f0000000001a20019000000000021004b00000000020000390000000102004039000005930010009c000015d10000213d0000000100200190000015d10000c13d0000002009900039000000400010043f0000000000a9043500000001077000390000000108800039000000000068004b000014180000413d0000000d0100002900000000010104330000000e0010006c000015c90000a13d0000000c010000290000000001010433000000400d00043d0000002402d0003900000040030000390000000000320435000005ab0200004100000000002d04350000000402d00039000000030300002900000000003204350000000f0500002900000000020504330000004403d0003900000000002304350000006403d0003900000005042002100000000006340019000000000002004b000000200c00008a000014990000613d0000000004000019000014870000013d0000001f087000390000000008c8016f0000000007670019000000000007043500000000066800190000000104400039000000000024004b000014990000813d0000000007d60049000000640770008a00000000037304360000002005500039000000000705043300000000870704340000000006760436000000000007004b0000147f0000613d0000000009000019000000000a690019000000000b980019000000000b0b04330000000000ba04350000002009900039000000000079004b000014910000413d0000147f0000013d00000591021001970000000001000414000000040020008c000014a30000c13d000000030100036700000001030000310000000004c3017000000000024d0019000014bd0000c13d000014c30000013d0000000003d600490000058a0030009c0000058a0300804100000060033002100000058a00d0009c00110000000d001d0000058a0400004100000000040d40190000004004400210000000000343019f0000058a0010009c0000058a01008041000000c001100210000000000113019f1624161f0000040f00000060031002700001058a0030019d0000058a0330019700030000000103550000000100200190000015fb0000613d000000200c00008a000000110d0000290000000004c3017000000000024d0019000014c30000613d000000000501034f00000000060d0019000000005705043c0000000006760436000000000026004b000014bf0000c13d0000001f05300190000014d00000613d000000000141034f0000000304500210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f00000000001204350000001f013000390000000001c1016f0000000002d10019000000000012004b00000000010000390000000101004039000700000002001d000005930020009c000015d10000213d0000000100100190000015d10000c13d0000000701000029000000400010043f000005ac0030009c000015cf0000213d000000200030008c000015cf0000413d00000000010d0433000005930010009c000015cf0000213d0000000002d300190000000001d100190000001f03100039000000000023004b0000000004000019000005ad04008041000005ad03300197000005ad05200197000000000653013f000000000053004b0000000003000019000005ad03004041000005ad0060009c000000000304c019000000000003004b000015cf0000c13d0000000016010434000005930060009c000015d10000213d00000005036002100000003f0430003900000594044001970000000704400029000005930040009c000015d10000213d000000400040043f00000007040000290000000004640436000500000004001d0000000003130019000000000023004b000015cf0000213d000000000031004b0000150e0000813d0000000702000029000000200220003900000000140104340000000000420435000000000031004b000015070000413d00000007010000290000000006010433000000000006004b000013d50000613d000000000700001900000010010000290000000e05000029000400000006001d0000151a0000013d000000100100002900000004060000290000000107700039000000000067004b000013d70000813d001000000001001d0000000d010000290000000001010433000000000051004b000015c90000a13d0000000f010000290000000001010433000000000071004b000015c90000a13d001100000007001d0000000502700210000900000002001d00000006022000290000000c0100002900000000010104330000059101100197000a00000002001d0000000002020433000b00000002001d000000000010043f000005ae01000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000015cf0000613d000000400200043d000000000101043b00000001031000390000000b010000290000000041010434000000000001004b000015480000613d000000000500001900000000062500190000000007540019000000000707043300000000007604350000002005500039000000000015004b000015410000413d000000000421001900000000003404350000058a0020009c0000058a02008041000000400220021000000020011000390000058a0010009c0000058a010080410000006001100210000000000121019f00000000020004140000058a0020009c0000058a02008041000000c002200210000000000112019f000005af011001c700008010020000391624161f0000040f0000000100200190000015cf0000613d000000000101043b0000000d0200002900000000020204330000000e0020006c0000001103000029000015c90000a13d0000000f020000290000000002020433000000000032004b000015c90000a13d000000000101041a000800000001001d0000000a010000290000000001010433000b00000001001d0000000c0100002900000000010104330000059101100197000000000010043f000005ae01000041000000200010043f00000000010004140000058a0010009c0000058a01008041000000c00110021000000599011001c700008010020000391624161f0000040f0000000100200190000015cf0000613d000000400200043d000000000101043b00000002031000390000000b010000290000000041010434000000000001004b000015890000613d000000000500001900000000062500190000000007540019000000000707043300000000007604350000002005500039000000000015004b000015820000413d000000000421001900000000003404350000058a0020009c0000058a02008041000000400220021000000020011000390000058a0010009c0000058a010080410000006001100210000000000121019f00000000020004140000058a0020009c0000058a02008041000000c002200210000000000112019f000005af011001c700008010020000391624161f0000040f0000000100200190000015cf0000613d000000000201043b000000070100002900000000010104330000001107000029000000000071004b0000000e05000029000015c90000a13d000000090300002900000005013000290000000004010433000000000004004b000015150000613d000000000202041a000000ff0220018f000000010020008c00000010010000290000000406000029000015dd0000213d000000000002004b000015b90000613d0000000803000029000000000003004b000015be0000613d00000000023400a900000000033200d9000000000043004b000015ba0000613d000015c20000013d0000000802000029000000000012001a000015c20000413d0000000001120019000015170000013d0000000002000019000000000010001a000015c20000413d000015bc0000013d000005a701000041000000000010043f0000001101000039000000040010043f000005a5010000410000162600010430000000000001042d000005a701000041000000000010043f0000003201000039000000040010043f000005a501000041000016260001043000000000010000190000162600010430000005a701000041000000000010043f0000004101000039000000040010043f000005a5010000410000162600010430000005a701000041000000000010043f0000002201000039000000040010043f000005a5010000410000162600010430000005a701000041000000000010043f0000002101000039000000040010043f000005a50100004100001626000104300000001f0530018f000005a606300198000000400200043d0000000004620019000016060000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000015ea0000c13d000016060000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000016060000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000015f60000c13d000016060000013d0000001f0530018f000005a606300198000000400200043d0000000004620019000016060000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000016020000c13d000000000005004b000016130000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500000060013002100000058a0020009c0000058a020080410000004002200210000000000121019f0000162600010430000005a701000041000000000010043f0000001201000039000000040010043f000005a501000041000016260001043000001622002104230000000102000039000000000001042d0000000002000019000000000001042d0000162400000432000016250001042e0000162600010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffff000000020000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000cf0fe89a00000000000000000000000000000000000000000000000000000000cf0fe89b00000000000000000000000000000000000000000000000000000000d87eca86000000000000000000000000000000000000000000000000000000001ed9518f000000000000000000000000000000000000000000000000000000009bca32b4000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffff7f000000000000000000000000000000000000000000000000ffffffffffffff1f000000000000000000000000000000000000000000000000ffffffffffffff9fcadbdeaa5eb735033c7cc6c45311fad3f405dcad29679d0ca2203b741cad7d6b0200000000000000000000000000000000000040000000000000000000000000357e7535c37cf7f9c3c7e51a7ae048037123a06207ebaf5817a6dd514fcfc748c5c34aa11a19eac62273f89f9b04ce7579d63213d50104b48f19d2dce88338e285233766bb78844f41198abb41d5038d096f993617a7860c12e140b15a5bf66e357e7535c37cf7f9c3c7e51a7ae048037123a06207ebaf5817a6dd514fcfc749d28f830c3d130f4f724af78f022cd402fadcb4431424226b6317a798c6e738d7de795ae769deb4643eeace76cd577adeda5df1672b464987a804a0af00517d11357e7535c37cf7f9c3c7e51a7ae048037123a06207ebaf5817a6dd514fcfc74ad823a2d6736ec7bcff61804abb2c416f52421e62f00c7ad312df05ec2c4c0faec678100f5c59846ece02b813b55b3eca165f8a056cf500a6043f9d1ffa2c38c7357e7535c37cf7f9c3c7e51a7ae048037123a06207ebaf5817a6dd514fcfc74c70a0823100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffe04e487b7100000000000000000000000000000000000000000000000000000000357e7535c37cf7f9c3c7e51a7ae048037123a06207ebaf5817a6dd514fcfc74d357e7535c37cf7f9c3c7e51a7ae048037123a06207ebaf5817a6dd514fcfc74e0200000000000000000000000000000000000020000000000000000000000000b7a700ef000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000357e7535c37cf7f9c3c7e51a7ae048037123a06207ebaf5817a6dd514fcfc74f0200000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000ffffffffffffffa0000000000000000000000000000000000000000000000000ffffffffffffff3f357e7535c37cf7f9c3c7e51a7ae048037123a06207ebaf5817a6dd514fcfc74b313ce567000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffeff01ffc9a700000000000000000000000000000000000000000000000000000000780e9d63000000000000000000000000000000000000000000000000000000002f745c59000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044000000000000000000000000c87b56dd000000000000000000000000000000000000000000000000000000000e89341c000000000000000000000000000000000000000000000000000000002cf02161a52c183876686d4a862ec33b368038f0003965ec65a48560f2049378

Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

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

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