diff --git a/Blastproof/blastproof.dsc b/Blastproof/blastproof.dsc index a64ade0..b578428 100644 --- a/Blastproof/blastproof.dsc +++ b/Blastproof/blastproof.dsc @@ -1,7 +1,7 @@ [Defines] DSC_SPECIFICATION = 0x0001001C PLATFORM_GUID = 040262ee-aebc-11f0-ba2c-10ffe08423a6 - PLATFORM_VERSION = 0.1 + PLATFORM_VERSION = 0.2 PLATFORM_NAME = BlastproofEnv SKUID_IDENTIFIER = DEFAULT SUPPORTED_ARCHITECTURES = X64 @@ -29,3 +29,6 @@ [Packages] MdePkg/MdePkg.dec + +[BuildOptions] + GCC:*_*_*_CC_FLAGS = -I$(WORKSPACE)/../ diff --git a/Blastproof/blastproof.json b/Blastproof/blastproof.json new file mode 100644 index 0000000..511a8c6 --- /dev/null +++ b/Blastproof/blastproof.json @@ -0,0 +1,73 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Blastproof build", + "actions":[ + { + "action":"ensure_folder_reset", + "args":{ + "path_variables":true, + "path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$" + } + }, + { + "action":"copy_folder", + "args":{ + "source_folder_variables":true, + "source_folder":"%rootcallerfolder%/Blastproof", + "destination_folder_variables":true, + "destination_folder":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$" + } + }, + { + "action":"run_submodule", + "args":{ + "file_variables":true, + "file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/common_crypto/common_crypto.json", + "wait":true, + "block_if_fail":true + } + }, + { + "action":"run_submodule_parallel", + "args":{ + "submodules_variables":true, + "submodules":[ + "%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/bootanim/bootanim.json", + "%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/fontgen/fontgen.json", + "%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/initfsgen/initfsgen.json", + "%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/config/config.json", + "%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/keygen/keygen.json" + ] + } + }, + { + "action":"run_submodule", + "args":{ + "file_variables":true, + "file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/keygen/keygen-run.json", + "wait":true, + "block_if_fail":true + } + }, + { + "action":"run_command_wait_dir", + "args":{ + "command_variables":true, + "command":[ + "bash", + "-c", + ". edksetup.sh; build --platform=Blastproof/blastproof.dsc --module=Blastproof/src/main.inf --arch=X64 --buildtarget=RELEASE --tagname=GCC" + ], + "success_status":[ + 0 + ], + "ignore_success_status":false, + "show_output":"on_failure", + "working_dir_variables":true, + "working_dir":"%rootcallerfolder%/$EDK2_DIR$" + } + } + ] +} diff --git a/Blastproof/bootanim/bootanim.cpp b/Blastproof/bootanim/bootanim.cpp index 64f0751..009209b 100644 --- a/Blastproof/bootanim/bootanim.cpp +++ b/Blastproof/bootanim/bootanim.cpp @@ -90,6 +90,10 @@ uint16_t clamp(long double v,uint16_t max) { return (uint16_t)v; } int main (int argc,char **argv) { + if (fs::exists("bootanim.bin")) { + cout<<"[Bootanim] Stopping here because bootanim.bin already exists."< +#include "params.h" + +/* The hash types that are passed to set_type */ +#define SPX_ADDR_TYPE_WOTS 0 +#define SPX_ADDR_TYPE_WOTSPK 1 +#define SPX_ADDR_TYPE_HASHTREE 2 +#define SPX_ADDR_TYPE_FORSTREE 3 +#define SPX_ADDR_TYPE_FORSPK 4 +#define SPX_ADDR_TYPE_WOTSPRF 5 +#define SPX_ADDR_TYPE_FORSPRF 6 + +#define set_layer_addr SPX_NAMESPACE(set_layer_addr) +void set_layer_addr(uint32_t addr[8], uint32_t layer); + +#define set_tree_addr SPX_NAMESPACE(set_tree_addr) +void set_tree_addr(uint32_t addr[8], uint64_t tree); + +#define set_type SPX_NAMESPACE(set_type) +void set_type(uint32_t addr[8], uint32_t type); + +/* Copies the layer and tree part of one address into the other */ +#define copy_subtree_addr SPX_NAMESPACE(copy_subtree_addr) +void copy_subtree_addr(uint32_t out[8], const uint32_t in[8]); + +/* These functions are used for WOTS and FORS addresses. */ + +#define set_keypair_addr SPX_NAMESPACE(set_keypair_addr) +void set_keypair_addr(uint32_t addr[8], uint32_t keypair); + +#define set_chain_addr SPX_NAMESPACE(set_chain_addr) +void set_chain_addr(uint32_t addr[8], uint32_t chain); + +#define set_hash_addr SPX_NAMESPACE(set_hash_addr) +void set_hash_addr(uint32_t addr[8], uint32_t hash); + +#define copy_keypair_addr SPX_NAMESPACE(copy_keypair_addr) +void copy_keypair_addr(uint32_t out[8], const uint32_t in[8]); + +/* These functions are used for all hash tree addresses (including FORS). */ + +#define set_tree_height SPX_NAMESPACE(set_tree_height) +void set_tree_height(uint32_t addr[8], uint32_t tree_height); + +#define set_tree_index SPX_NAMESPACE(set_tree_index) +void set_tree_index(uint32_t addr[8], uint32_t tree_index); + +#endif diff --git a/Blastproof/common_crypto/api.h b/Blastproof/common_crypto/api.h new file mode 100644 index 0000000..d57a148 --- /dev/null +++ b/Blastproof/common_crypto/api.h @@ -0,0 +1,77 @@ +#ifndef SPX_API_H +#define SPX_API_H + +#include +#include + +#include "params.h" + +#define CRYPTO_ALGNAME "SPHINCS+" + +#define CRYPTO_SECRETKEYBYTES SPX_SK_BYTES +#define CRYPTO_PUBLICKEYBYTES SPX_PK_BYTES +#define CRYPTO_BYTES SPX_BYTES +#define CRYPTO_SEEDBYTES 3*SPX_N + +/* + * Returns the length of a secret key, in bytes + */ +unsigned long long crypto_sign_secretkeybytes(void); + +/* + * Returns the length of a public key, in bytes + */ +unsigned long long crypto_sign_publickeybytes(void); + +/* + * Returns the length of a signature, in bytes + */ +unsigned long long crypto_sign_bytes(void); + +/* + * Returns the length of the seed required to generate a key pair, in bytes + */ +unsigned long long crypto_sign_seedbytes(void); + +/* + * Generates a SPHINCS+ key pair given a seed. + * Format sk: [SK_SEED || SK_PRF || PUB_SEED || root] + * Format pk: [root || PUB_SEED] + */ +int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed); + +/* + * Generates a SPHINCS+ key pair. + * Format sk: [SK_SEED || SK_PRF || PUB_SEED || root] + * Format pk: [root || PUB_SEED] + */ +int crypto_sign_keypair(unsigned char *pk, unsigned char *sk); + +/** + * Returns an array containing a detached signature. + */ +int crypto_sign_signature(uint8_t *sig, size_t *siglen, + const uint8_t *m, size_t mlen, const uint8_t *sk); + +/** + * Verifies a detached signature and message under a given public key. + */ +int crypto_sign_verify(const uint8_t *sig, size_t siglen, + const uint8_t *m, size_t mlen, const uint8_t *pk); + +/** + * Returns an array containing the signature followed by the message. + */ +int crypto_sign(unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk); + +/** + * Verifies a given signature-message pair under a given public key. + */ +int crypto_sign_open(unsigned char *m, unsigned long long *mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk); + +#endif diff --git a/Blastproof/keygen/argon2/src/argon2.c b/Blastproof/common_crypto/argon2.c similarity index 100% rename from Blastproof/keygen/argon2/src/argon2.c rename to Blastproof/common_crypto/argon2.c diff --git a/Blastproof/common_crypto/argon2.h b/Blastproof/common_crypto/argon2.h new file mode 100644 index 0000000..3980bb3 --- /dev/null +++ b/Blastproof/common_crypto/argon2.h @@ -0,0 +1,437 @@ +/* + * Argon2 reference source code package - reference C implementations + * + * Copyright 2015 + * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves + * + * You may use this work under the terms of a Creative Commons CC0 1.0 + * License/Waiver or the Apache Public License 2.0, at your option. The terms of + * these licenses can be found at: + * + * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 + * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 + * + * You should have received a copy of both of these licenses along with this + * software. If not, they may be obtained at the above URLs. + */ + +#ifndef ARGON2_H +#define ARGON2_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Symbols visibility control */ +#ifdef A2_VISCTL +#define ARGON2_PUBLIC __attribute__((visibility("default"))) +#define ARGON2_LOCAL __attribute__ ((visibility ("hidden"))) +#elif defined(_MSC_VER) +#define ARGON2_PUBLIC __declspec(dllexport) +#define ARGON2_LOCAL +#else +#define ARGON2_PUBLIC +#define ARGON2_LOCAL +#endif + +/* + * Argon2 input parameter restrictions + */ + +/* Minimum and maximum number of lanes (degree of parallelism) */ +#define ARGON2_MIN_LANES UINT32_C(1) +#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) + +/* Minimum and maximum number of threads */ +#define ARGON2_MIN_THREADS UINT32_C(1) +#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) + +/* Number of synchronization points between lanes per pass */ +#define ARGON2_SYNC_POINTS UINT32_C(4) + +/* Minimum and maximum digest size in bytes */ +#define ARGON2_MIN_OUTLEN UINT32_C(4) +#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ +#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */ + +#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) +/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */ +#define ARGON2_MAX_MEMORY_BITS \ + ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) +#define ARGON2_MAX_MEMORY \ + ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) + +/* Minimum and maximum number of passes */ +#define ARGON2_MIN_TIME UINT32_C(1) +#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum password length in bytes */ +#define ARGON2_MIN_PWD_LENGTH UINT32_C(0) +#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum associated data length in bytes */ +#define ARGON2_MIN_AD_LENGTH UINT32_C(0) +#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum salt length in bytes */ +#define ARGON2_MIN_SALT_LENGTH UINT32_C(8) +#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum key length in bytes */ +#define ARGON2_MIN_SECRET UINT32_C(0) +#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) + +/* Flags to determine which fields are securely wiped (default = no wipe). */ +#define ARGON2_DEFAULT_FLAGS UINT32_C(0) +#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) +#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) + +/* Global flag to determine if we are wiping internal memory buffers. This flag + * is defined in core.c and defaults to 1 (wipe internal memory). */ +extern int FLAG_clear_internal_memory; + +/* Error codes */ +typedef enum Argon2_ErrorCodes { + ARGON2_OK = 0, + + ARGON2_OUTPUT_PTR_NULL = -1, + + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, + + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, + + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, + + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, + + ARGON2_SECRET_TOO_SHORT = -10, + ARGON2_SECRET_TOO_LONG = -11, + + ARGON2_TIME_TOO_SMALL = -12, + ARGON2_TIME_TOO_LARGE = -13, + + ARGON2_MEMORY_TOO_LITTLE = -14, + ARGON2_MEMORY_TOO_MUCH = -15, + + ARGON2_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, + + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + + ARGON2_MEMORY_ALLOCATION_ERROR = -22, + + ARGON2_FREE_MEMORY_CBK_NULL = -23, + ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, + + ARGON2_INCORRECT_PARAMETER = -25, + ARGON2_INCORRECT_TYPE = -26, + + ARGON2_OUT_PTR_MISMATCH = -27, + + ARGON2_THREADS_TOO_FEW = -28, + ARGON2_THREADS_TOO_MANY = -29, + + ARGON2_MISSING_ARGS = -30, + + ARGON2_ENCODING_FAIL = -31, + + ARGON2_DECODING_FAIL = -32, + + ARGON2_THREAD_FAIL = -33, + + ARGON2_DECODING_LENGTH_FAIL = -34, + + ARGON2_VERIFY_MISMATCH = -35 +} argon2_error_codes; + +/* Memory allocator types --- for external allocation */ +typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate); +typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); + +/* Argon2 external data structures */ + +/* + ***** + * Context: structure to hold Argon2 inputs: + * output array and its length, + * password and its length, + * salt and its length, + * secret and its length, + * associated data and its length, + * number of passes, amount of used memory (in KBytes, can be rounded up a bit) + * number of parallel threads that will be run. + * All the parameters above affect the output hash value. + * Additionally, two function pointers can be provided to allocate and + * deallocate the memory (if NULL, memory will be allocated internally). + * Also, three flags indicate whether to erase password, secret as soon as they + * are pre-hashed (and thus not needed anymore), and the entire memory + ***** + * Simplest situation: you have output array out[8], password is stored in + * pwd[32], salt is stored in salt[16], you do not have keys nor associated + * data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with + * 4 parallel lanes. + * You want to erase the password, but you're OK with last pass not being + * erased. You want to use the default memory allocator. + * Then you initialize: + Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) + */ +typedef struct Argon2_Context { + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ + + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ + + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ + + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ + + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ + + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ + + uint32_t version; /* version number */ + + allocate_fptr allocate_cbk; /* pointer to memory allocator */ + deallocate_fptr free_cbk; /* pointer to memory deallocator */ + + uint32_t flags; /* array of bool options */ +} argon2_context; + +/* Argon2 primitive type */ +typedef enum Argon2_type { + Argon2_d = 0, + Argon2_i = 1, + Argon2_id = 2 +} argon2_type; + +/* Version of the algorithm */ +typedef enum Argon2_version { + ARGON2_VERSION_10 = 0x10, + ARGON2_VERSION_13 = 0x13, + ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 +} argon2_version; + +/* + * Function that gives the string representation of an argon2_type. + * @param type The argon2_type that we want the string for + * @param uppercase Whether the string should have the first letter uppercase + * @return NULL if invalid type, otherwise the string representation. + */ +ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase); + +/* + * Function that performs memory-hard hashing with certain degree of parallelism + * @param context Pointer to the Argon2 internal structure + * @return Error code if smth is wrong, ARGON2_OK otherwise + */ +ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type); + +/** + * Hashes a password with Argon2i, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +/** + * Hashes a password with Argon2i, producing a raw hash at @hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash - updated by the function + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, + const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, + const size_t hashlen, char *encoded, + const size_t encodedlen); + +ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost, + const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, + const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type, + const uint32_t version); + +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd, + const size_t pwdlen); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd, + const size_t pwdlen, argon2_type type); + +/** + * Argon2d: Version of Argon2 that picks memory blocks depending + * on the password and salt. Only for side-channel-free + * environment!! + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2d_ctx(argon2_context *context); + +/** + * Argon2i: Version of Argon2 that picks memory blocks + * independent on the password and salt. Good for side-channels, + * but worse w.r.t. tradeoff attacks if only one pass is used. + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2i_ctx(argon2_context *context); + +/** + * Argon2id: Version of Argon2 where the first half-pass over memory is + * password-independent, the rest are password-dependent (on the password and + * salt). OK against side channels (they reduce to 1/2-pass Argon2i), and + * better with w.r.t. tradeoff attacks (similar to Argon2d). + ***** + * @param context Pointer to current Argon2 context + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2id_ctx(argon2_context *context); + +/** + * Verify if a given password is correct for Argon2d hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash); + +/** + * Verify if a given password is correct for Argon2i hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash); + +/** + * Verify if a given password is correct for Argon2id hashing + * @param context Pointer to current Argon2 context + * @param hash The password hash to verify. The length of the hash is + * specified by the context outlen member + * @return Zero if successful, a non zero error code otherwise + */ +ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context, + const char *hash); + +/* generic function underlying the above ones */ +ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash, + argon2_type type); + +/** + * Get the associated error message for given error code + * @return The error message associated with the given error code + */ +ARGON2_PUBLIC const char *argon2_error_message(int error_code); + +/** + * Returns the encoded hash length for the given input parameters + * @param t_cost Number of iterations + * @param m_cost Memory usage in kibibytes + * @param parallelism Number of threads; used to compute lanes + * @param saltlen Salt size in bytes + * @param hashlen Hash size in bytes + * @param type The argon2_type that we want the encoded length for + * @return The encoded hash length in bytes + */ +ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, + uint32_t parallelism, uint32_t saltlen, + uint32_t hashlen, argon2_type type); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/Blastproof/keygen/argon2/src/blake2/blake2-impl.h b/Blastproof/common_crypto/blake2/blake2-impl.h similarity index 100% rename from Blastproof/keygen/argon2/src/blake2/blake2-impl.h rename to Blastproof/common_crypto/blake2/blake2-impl.h diff --git a/Blastproof/keygen/argon2/src/blake2/blake2.h b/Blastproof/common_crypto/blake2/blake2.h similarity index 99% rename from Blastproof/keygen/argon2/src/blake2/blake2.h rename to Blastproof/common_crypto/blake2/blake2.h index 501c6a3..0c1b0ee 100644 --- a/Blastproof/keygen/argon2/src/blake2/blake2.h +++ b/Blastproof/common_crypto/blake2/blake2.h @@ -18,7 +18,7 @@ #ifndef PORTABLE_BLAKE2_H #define PORTABLE_BLAKE2_H -#include +#include "../argon2.h" #if defined(__cplusplus) extern "C" { diff --git a/Blastproof/keygen/argon2/src/blake2/blake2b.c b/Blastproof/common_crypto/blake2/blake2b.c similarity index 100% rename from Blastproof/keygen/argon2/src/blake2/blake2b.c rename to Blastproof/common_crypto/blake2/blake2b.c diff --git a/Blastproof/keygen/argon2/src/blake2/blamka-round-opt.h b/Blastproof/common_crypto/blake2/blamka-round-opt.h similarity index 100% rename from Blastproof/keygen/argon2/src/blake2/blamka-round-opt.h rename to Blastproof/common_crypto/blake2/blamka-round-opt.h diff --git a/Blastproof/keygen/argon2/src/blake2/blamka-round-ref.h b/Blastproof/common_crypto/blake2/blamka-round-ref.h similarity index 100% rename from Blastproof/keygen/argon2/src/blake2/blamka-round-ref.h rename to Blastproof/common_crypto/blake2/blamka-round-ref.h diff --git a/Blastproof/common_crypto/common_crypto.json b/Blastproof/common_crypto/common_crypto.json new file mode 100644 index 0000000..732dc31 --- /dev/null +++ b/Blastproof/common_crypto/common_crypto.json @@ -0,0 +1,140 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Common Crypto build", + "actions":[ + { + "action":"compile_multiple_cpp", + "args":{ + "source_files_path_completion":true, + "path_completion_source_ext":".c", + "path_completion_output_ext":".o", + "source_files_variables":true, + "source_files":[ + "%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/common_crypto/**" + ], + "compiler_variables":true, + "compiler":"$C_COMPILER$", + "pre_arguments_variables":true, + "pre_arguments":[ + "-c" + ], + "post_arguments_variables":true, + "post_arguments":[ + "-o", + "%outputfile%", + "-Ofast", + "-march=native", + "-fPIC" + ], + "output_files_variables":false, + "output_files":[ + ], + "success_status":[ + 0 + ], + "ignore_success_status":false, + "cache_authorized":true, + "headers_command_variables":true, + "headers_command":"gcc -MMD -MF %dfile% -E %sourcefile% -o /dev/null" + } + }, + { + "action":"run_command_wait", + "args":{ + "command_variables":false, + "command":[ + "ar", + "rcs", + "libcommoncrypto.a", + "address.o", + "fors.o", + "hash_sha2.o", + "merkle.o", + "randombytes.o", + "sha2.o", + "sha3.o", + "sign.o", + "utils.o", + "utilsx1.o", + "wots.o", + "wotsx1.o", + "thash_sha2_robust.o", + "argon2.o", + "blake2/blake2b.o", + "core.o", + "encoding.o", + "opt.o", + "thread.o" + ], + "success_status":[ + 0 + ], + "ignore_success_status":false, + "show_output":"on_failure" + } + }, + { + "action":"run_command_wait", + "args":{ + "command_variables":true, + "command":[ + "$C_COMPILER$", + "--shared", + "-o", + "libcommoncrypto.so", + "address.o", + "fors.o", + "hash_sha2.o", + "merkle.o", + "randombytes.o", + "sha2.o", + "sha3.o", + "sign.o", + "utils.o", + "utilsx1.o", + "wots.o", + "wotsx1.o", + "thash_sha2_robust.o", + "argon2.o", + "blake2/blake2b.o", + "core.o", + "encoding.o", + "opt.o", + "thread.o" + ], + "success_status":[ + 0 + ], + "ignore_success_status":false, + "show_output":"on_failure" + } + }, + { + "action":"vftm_load_crypto_lib", + "args":{ + "lib_path_variables":true, + "lib_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/common_crypto/libcommoncrypto.so" + } + }, + { + "action":"copy_file", + "args":{ + "source_file_variables":true, + "source_file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/common_crypto/libcommoncrypto.a", + "destination_folder_variables":true, + "destination_folder":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/keygen/libcommoncrypto.a" + } + }, + { + "action":"copy_file", + "args":{ + "source_file_variables":true, + "source_file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/common_crypto/libcommoncrypto.a", + "destination_folder_variables":true, + "destination_folder":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/initfsgen/libcommoncrypto.a" + } + } + ] +} diff --git a/Blastproof/common_crypto/context.h b/Blastproof/common_crypto/context.h new file mode 100644 index 0000000..aded564 --- /dev/null +++ b/Blastproof/common_crypto/context.h @@ -0,0 +1,28 @@ +#ifndef SPX_CONTEXT_H +#define SPX_CONTEXT_H + +#include + +#include "params.h" + +typedef struct { + uint8_t pub_seed[SPX_N]; + uint8_t sk_seed[SPX_N]; + +#ifdef SPX_SHA2 + // sha256 state that absorbed pub_seed + uint8_t state_seeded[40]; + +# if SPX_SHA512 + // sha512 state that absorbed pub_seed + uint8_t state_seeded_512[72]; +# endif +#endif + +#ifdef SPX_HARAKA + uint64_t tweaked512_rc64[10][8]; + uint32_t tweaked256_rc32[10][8]; +#endif +} spx_ctx; + +#endif diff --git a/Blastproof/keygen/argon2/src/core.c b/Blastproof/common_crypto/core.c similarity index 100% rename from Blastproof/keygen/argon2/src/core.c rename to Blastproof/common_crypto/core.c diff --git a/Blastproof/keygen/argon2/src/core.h b/Blastproof/common_crypto/core.h similarity index 100% rename from Blastproof/keygen/argon2/src/core.h rename to Blastproof/common_crypto/core.h diff --git a/Blastproof/keygen/argon2/src/encoding.c b/Blastproof/common_crypto/encoding.c similarity index 100% rename from Blastproof/keygen/argon2/src/encoding.c rename to Blastproof/common_crypto/encoding.c diff --git a/Blastproof/keygen/argon2/src/encoding.h b/Blastproof/common_crypto/encoding.h similarity index 100% rename from Blastproof/keygen/argon2/src/encoding.h rename to Blastproof/common_crypto/encoding.h diff --git a/Blastproof/initfsgen/fors.c b/Blastproof/common_crypto/fors.c similarity index 100% rename from Blastproof/initfsgen/fors.c rename to Blastproof/common_crypto/fors.c diff --git a/Blastproof/common_crypto/fors.h b/Blastproof/common_crypto/fors.h new file mode 100644 index 0000000..8d98017 --- /dev/null +++ b/Blastproof/common_crypto/fors.h @@ -0,0 +1,32 @@ +#ifndef SPX_FORS_H +#define SPX_FORS_H + +#include + +#include "params.h" +#include "context.h" + +/** + * Signs a message m, deriving the secret key from sk_seed and the FTS address. + * Assumes m contains at least SPX_FORS_HEIGHT * SPX_FORS_TREES bits. + */ +#define fors_sign SPX_NAMESPACE(fors_sign) +void fors_sign(unsigned char *sig, unsigned char *pk, + const unsigned char *m, + const spx_ctx* ctx, + const uint32_t fors_addr[8]); + +/** + * Derives the FORS public key from a signature. + * This can be used for verification by comparing to a known public key, or to + * subsequently verify a signature on the derived public key. The latter is the + * typical use-case when used as an FTS below an OTS in a hypertree. + * Assumes m contains at least SPX_FORS_HEIGHT * SPX_FORS_TREES bits. + */ +#define fors_pk_from_sig SPX_NAMESPACE(fors_pk_from_sig) +void fors_pk_from_sig(unsigned char *pk, + const unsigned char *sig, const unsigned char *m, + const spx_ctx* ctx, + const uint32_t fors_addr[8]); + +#endif diff --git a/Blastproof/common_crypto/hash.h b/Blastproof/common_crypto/hash.h new file mode 100644 index 0000000..b141f09 --- /dev/null +++ b/Blastproof/common_crypto/hash.h @@ -0,0 +1,27 @@ +#ifndef SPX_HASH_H +#define SPX_HASH_H + +#include +#include "context.h" +#include "params.h" + +#define initialize_hash_function SPX_NAMESPACE(initialize_hash_function) +void initialize_hash_function(spx_ctx *ctx); + +#define prf_addr SPX_NAMESPACE(prf_addr) +void prf_addr(unsigned char *out, const spx_ctx *ctx, + const uint32_t addr[8]); + +#define gen_message_random SPX_NAMESPACE(gen_message_random) +void gen_message_random(unsigned char *R, const unsigned char *sk_prf, + const unsigned char *optrand, + const unsigned char *m, unsigned long long mlen, + const spx_ctx *ctx); + +#define hash_message SPX_NAMESPACE(hash_message) +void hash_message(unsigned char *digest, uint64_t *tree, uint32_t *leaf_idx, + const unsigned char *R, const unsigned char *pk, + const unsigned char *m, unsigned long long mlen, + const spx_ctx *ctx); + +#endif diff --git a/Blastproof/initfsgen/hash_sha2.c b/Blastproof/common_crypto/hash_sha2.c similarity index 100% rename from Blastproof/initfsgen/hash_sha2.c rename to Blastproof/common_crypto/hash_sha2.c diff --git a/Blastproof/initfsgen/merkle.c b/Blastproof/common_crypto/merkle.c similarity index 100% rename from Blastproof/initfsgen/merkle.c rename to Blastproof/common_crypto/merkle.c diff --git a/Blastproof/common_crypto/merkle.h b/Blastproof/common_crypto/merkle.h new file mode 100644 index 0000000..9ac2759 --- /dev/null +++ b/Blastproof/common_crypto/merkle.h @@ -0,0 +1,18 @@ +#if !defined( MERKLE_H_ ) +#define MERKLE_H_ + +#include + +/* Generate a Merkle signature (WOTS signature followed by the Merkle */ +/* authentication path) */ +#define merkle_sign SPX_NAMESPACE(merkle_sign) +void merkle_sign(uint8_t *sig, unsigned char *root, + const spx_ctx* ctx, + uint32_t wots_addr[8], uint32_t tree_addr[8], + uint32_t idx_leaf); + +/* Compute the root node of the top-most subtree. */ +#define merkle_gen_root SPX_NAMESPACE(merkle_gen_root) +void merkle_gen_root(unsigned char *root, const spx_ctx* ctx); + +#endif /* MERKLE_H_ */ diff --git a/Blastproof/keygen/argon2/src/opt.c b/Blastproof/common_crypto/opt.c similarity index 100% rename from Blastproof/keygen/argon2/src/opt.c rename to Blastproof/common_crypto/opt.c diff --git a/Blastproof/common_crypto/params.h b/Blastproof/common_crypto/params.h new file mode 100644 index 0000000..6dc6974 --- /dev/null +++ b/Blastproof/common_crypto/params.h @@ -0,0 +1,3 @@ +#define str(s) #s +#define xstr(s) str(s) +#include "params/params-sphincs-sha2-256f.h" diff --git a/Blastproof/common_crypto/params/params-sphincs-sha2-256f.h b/Blastproof/common_crypto/params/params-sphincs-sha2-256f.h new file mode 100644 index 0000000..53c5bef --- /dev/null +++ b/Blastproof/common_crypto/params/params-sphincs-sha2-256f.h @@ -0,0 +1,85 @@ +#ifndef SPX_PARAMS_H +#define SPX_PARAMS_H + +#define SPX_NAMESPACE(s) SPX_##s + +/* Hash output length in bytes. */ +#define SPX_N 32 +/* Height of the hypertree. */ +#define SPX_FULL_HEIGHT 68 +/* Number of subtree layer. */ +#define SPX_D 17 +/* FORS tree dimensions. */ +#define SPX_FORS_HEIGHT 9 +#define SPX_FORS_TREES 35 +/* Winternitz parameter, */ +#define SPX_WOTS_W 16 + +/* The hash function is defined by linking a different hash.c file, as opposed + to setting a #define constant. */ + +/* This is a SHA2-based parameter set, hence whether we use SHA-256 + * exclusively or we use both SHA-256 and SHA-512 is controlled by + * the following #define */ +#define SPX_SHA512 1 /* Use SHA-512 for H and T_l, l >= 2 */ + +/* For clarity */ +#define SPX_ADDR_BYTES 32 + +/* WOTS parameters. */ +#if SPX_WOTS_W == 256 + #define SPX_WOTS_LOGW 8 +#elif SPX_WOTS_W == 16 + #define SPX_WOTS_LOGW 4 +#else + #error SPX_WOTS_W assumed 16 or 256 +#endif + +#define SPX_WOTS_LEN1 (8 * SPX_N / SPX_WOTS_LOGW) + +/* SPX_WOTS_LEN2 is floor(log(len_1 * (w - 1)) / log(w)) + 1; we precompute */ +#if SPX_WOTS_W == 256 + #if SPX_N <= 1 + #define SPX_WOTS_LEN2 1 + #elif SPX_N <= 256 + #define SPX_WOTS_LEN2 2 + #else + #error Did not precompute SPX_WOTS_LEN2 for n outside {2, .., 256} + #endif +#elif SPX_WOTS_W == 16 + #if SPX_N <= 8 + #define SPX_WOTS_LEN2 2 + #elif SPX_N <= 136 + #define SPX_WOTS_LEN2 3 + #elif SPX_N <= 256 + #define SPX_WOTS_LEN2 4 + #else + #error Did not precompute SPX_WOTS_LEN2 for n outside {2, .., 256} + #endif +#endif + +#define SPX_WOTS_LEN (SPX_WOTS_LEN1 + SPX_WOTS_LEN2) +#define SPX_WOTS_BYTES (SPX_WOTS_LEN * SPX_N) +#define SPX_WOTS_PK_BYTES SPX_WOTS_BYTES + +/* Subtree size. */ +#define SPX_TREE_HEIGHT (SPX_FULL_HEIGHT / SPX_D) + +#if SPX_TREE_HEIGHT * SPX_D != SPX_FULL_HEIGHT + #error SPX_D should always divide SPX_FULL_HEIGHT +#endif + +/* FORS parameters. */ +#define SPX_FORS_MSG_BYTES ((SPX_FORS_HEIGHT * SPX_FORS_TREES + 7) / 8) +#define SPX_FORS_BYTES ((SPX_FORS_HEIGHT + 1) * SPX_FORS_TREES * SPX_N) +#define SPX_FORS_PK_BYTES SPX_N + +/* Resulting SPX sizes. */ +#define SPX_BYTES (SPX_N + SPX_FORS_BYTES + SPX_D * SPX_WOTS_BYTES +\ + SPX_FULL_HEIGHT * SPX_N) +#define SPX_PK_BYTES (2 * SPX_N) +#define SPX_SK_BYTES (2 * SPX_N + SPX_PK_BYTES) + +#include "../sha2_offsets.h" + +#endif diff --git a/Blastproof/initfsgen/randombytes.c b/Blastproof/common_crypto/randombytes.c similarity index 100% rename from Blastproof/initfsgen/randombytes.c rename to Blastproof/common_crypto/randombytes.c diff --git a/Blastproof/common_crypto/randombytes.h b/Blastproof/common_crypto/randombytes.h new file mode 100644 index 0000000..671c1b1 --- /dev/null +++ b/Blastproof/common_crypto/randombytes.h @@ -0,0 +1,6 @@ +#ifndef SPX_RANDOMBYTES_H +#define SPX_RANDOMBYTES_H + +extern void randombytes(unsigned char * x,unsigned long long xlen); + +#endif diff --git a/Blastproof/initfsgen/sha2.c b/Blastproof/common_crypto/sha2.c similarity index 100% rename from Blastproof/initfsgen/sha2.c rename to Blastproof/common_crypto/sha2.c diff --git a/Blastproof/common_crypto/sha2.h b/Blastproof/common_crypto/sha2.h new file mode 100644 index 0000000..732ab4b --- /dev/null +++ b/Blastproof/common_crypto/sha2.h @@ -0,0 +1,43 @@ +#ifndef SPX_SHA2_H +#define SPX_SHA2_H + +#include "params.h" + +#define SPX_SHA256_BLOCK_BYTES 64 +#define SPX_SHA256_OUTPUT_BYTES 32 /* This does not necessarily equal SPX_N */ + +#define SPX_SHA512_BLOCK_BYTES 128 +#define SPX_SHA512_OUTPUT_BYTES 64 + +#if SPX_SHA256_OUTPUT_BYTES < SPX_N + #error Linking against SHA-256 with N larger than 32 bytes is not supported +#endif + +#define SPX_SHA256_ADDR_BYTES 22 + +#include +#include + +void sha256_inc_init(uint8_t *state); +void sha256_inc_blocks(uint8_t *state, const uint8_t *in, size_t inblocks); +void sha256_inc_finalize(uint8_t *out, uint8_t *state, const uint8_t *in, size_t inlen); +void sha256(uint8_t *out, const uint8_t *in, size_t inlen); + +void sha512_inc_init(uint8_t *state); +void sha512_inc_blocks(uint8_t *state, const uint8_t *in, size_t inblocks); +void sha512_inc_finalize(uint8_t *out, uint8_t *state, const uint8_t *in, size_t inlen); +void sha512(uint8_t *out, const uint8_t *in, size_t inlen); + +#define mgf1_256 SPX_NAMESPACE(mgf1_256) +void mgf1_256(unsigned char *out, unsigned long outlen, + const unsigned char *in, unsigned long inlen); + +#define mgf1_512 SPX_NAMESPACE(mgf1_512) +void mgf1_512(unsigned char *out, unsigned long outlen, + const unsigned char *in, unsigned long inlen); + +#define seed_state SPX_NAMESPACE(seed_state) +void seed_state(spx_ctx *ctx); + + +#endif diff --git a/Blastproof/common_crypto/sha2_offsets.h b/Blastproof/common_crypto/sha2_offsets.h new file mode 100644 index 0000000..49f7e85 --- /dev/null +++ b/Blastproof/common_crypto/sha2_offsets.h @@ -0,0 +1,20 @@ +#ifndef SHA2_OFFSETS_H_ +#define SHA2_OFFSETS_H_ + +/* + * Offsets of various fields in the address structure when we use SHA2 as + * the Sphincs+ hash function + */ + +#define SPX_OFFSET_LAYER 0 /* The byte used to specify the Merkle tree layer */ +#define SPX_OFFSET_TREE 1 /* The start of the 8 byte field used to specify the tree */ +#define SPX_OFFSET_TYPE 9 /* The byte used to specify the hash type (reason) */ +#define SPX_OFFSET_KP_ADDR 10 /* The start of the 4 byte field used to specify the key pair address */ +#define SPX_OFFSET_CHAIN_ADDR 17 /* The byte used to specify the chain address (which Winternitz chain) */ +#define SPX_OFFSET_HASH_ADDR 21 /* The byte used to specify the hash address (where in the Winternitz chain) */ +#define SPX_OFFSET_TREE_HGT 17 /* The byte used to specify the height of this node in the FORS or Merkle tree */ +#define SPX_OFFSET_TREE_INDEX 18 /* The start of the 4 byte field used to specify the node in the FORS or Merkle tree */ + +#define SPX_SHA2 1 + +#endif /* SHA2_OFFSETS_H_ */ diff --git a/Blastproof/initfsgen/sha3.c b/Blastproof/common_crypto/sha3.c similarity index 100% rename from Blastproof/initfsgen/sha3.c rename to Blastproof/common_crypto/sha3.c diff --git a/Blastproof/common_crypto/sha3.h b/Blastproof/common_crypto/sha3.h new file mode 100644 index 0000000..4431c49 --- /dev/null +++ b/Blastproof/common_crypto/sha3.h @@ -0,0 +1,46 @@ +// sha3.h +// 19-Nov-11 Markku-Juhani O. Saarinen + +#ifndef SHA3_H +#define SHA3_H + +#include +#include + +#ifndef KECCAKF_ROUNDS +#define KECCAKF_ROUNDS 24 +#endif + +#ifndef ROTL64 +#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) +#endif + +// state context +typedef struct { + union { // state: + uint8_t b[200]; // 8-bit bytes + uint64_t q[25]; // 64-bit words + } st; + int pt, rsiz, mdlen; // these don't overflow +} sha3_ctx_t; + +// Compression function. +void sha3_keccakf(uint64_t st[25]); + +// OpenSSL - like interfece +int sha3_init(sha3_ctx_t *c, int mdlen); // mdlen = hash output in bytes +int sha3_update(sha3_ctx_t *c, const void *data, size_t len); +int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md + +// compute a sha3 hash (md) of given byte length from "in" +void *sha3(const void *in, size_t inlen, void *md, int mdlen); + +// SHAKE128 and SHAKE256 extensible-output functions +#define shake128_init(c) sha3_init(c, 16) +#define shake256_init(c) sha3_init(c, 32) +#define shake_update sha3_update + +void shake_xof(sha3_ctx_t *c); +void shake_out(sha3_ctx_t *c, void *out, size_t len); + +#endif diff --git a/Blastproof/initfsgen/sign.c b/Blastproof/common_crypto/sign.c similarity index 100% rename from Blastproof/initfsgen/sign.c rename to Blastproof/common_crypto/sign.c diff --git a/Blastproof/common_crypto/thash.h b/Blastproof/common_crypto/thash.h new file mode 100644 index 0000000..8687ccf --- /dev/null +++ b/Blastproof/common_crypto/thash.h @@ -0,0 +1,13 @@ +#ifndef SPX_THASH_H +#define SPX_THASH_H + +#include "context.h" +#include "params.h" + +#include + +#define thash SPX_NAMESPACE(thash) +void thash(unsigned char *out, const unsigned char *in, unsigned int inblocks, + const spx_ctx *ctx, uint32_t addr[8]); + +#endif diff --git a/Blastproof/initfsgen/thash_sha2_robust.c b/Blastproof/common_crypto/thash_sha2_robust.c similarity index 100% rename from Blastproof/initfsgen/thash_sha2_robust.c rename to Blastproof/common_crypto/thash_sha2_robust.c diff --git a/Blastproof/initfsgen/thash_sha2_simple.c b/Blastproof/common_crypto/thash_sha2_simple.c similarity index 100% rename from Blastproof/initfsgen/thash_sha2_simple.c rename to Blastproof/common_crypto/thash_sha2_simple.c diff --git a/Blastproof/keygen/argon2/src/thread.c b/Blastproof/common_crypto/thread.c similarity index 100% rename from Blastproof/keygen/argon2/src/thread.c rename to Blastproof/common_crypto/thread.c diff --git a/Blastproof/keygen/argon2/src/thread.h b/Blastproof/common_crypto/thread.h similarity index 100% rename from Blastproof/keygen/argon2/src/thread.h rename to Blastproof/common_crypto/thread.h diff --git a/Blastproof/initfsgen/utils.c b/Blastproof/common_crypto/utils.c similarity index 100% rename from Blastproof/initfsgen/utils.c rename to Blastproof/common_crypto/utils.c diff --git a/Blastproof/common_crypto/utils.h b/Blastproof/common_crypto/utils.h new file mode 100644 index 0000000..b13502c --- /dev/null +++ b/Blastproof/common_crypto/utils.h @@ -0,0 +1,64 @@ +#ifndef SPX_UTILS_H +#define SPX_UTILS_H + +#include +#include "params.h" +#include "context.h" + + +/* To support MSVC use alloca() instead of VLAs. See #20. */ +#ifdef _MSC_VER +/* MSVC defines _alloca in malloc.h */ +# include +/* Note: _malloca(), which is recommended over deprecated _alloca, + requires that you call _freea(). So we stick with _alloca */ +# define SPX_VLA(__t,__x,__s) __t *__x = (__t*)_alloca((__s)*sizeof(__t)) +#else +# define SPX_VLA(__t,__x,__s) __t __x[__s] +#endif + +/** + * Converts the value of 'in' to 'outlen' bytes in big-endian byte order. + */ +#define ull_to_bytes SPX_NAMESPACE(ull_to_bytes) +void ull_to_bytes(unsigned char *out, unsigned int outlen, + unsigned long long in); +#define u32_to_bytes SPX_NAMESPACE(u32_to_bytes) +void u32_to_bytes(unsigned char *out, uint32_t in); + +/** + * Converts the inlen bytes in 'in' from big-endian byte order to an integer. + */ +#define bytes_to_ull SPX_NAMESPACE(bytes_to_ull) +unsigned long long bytes_to_ull(const unsigned char *in, unsigned int inlen); + +/** + * Computes a root node given a leaf and an auth path. + * Expects address to be complete other than the tree_height and tree_index. + */ +#define compute_root SPX_NAMESPACE(compute_root) +void compute_root(unsigned char *root, const unsigned char *leaf, + uint32_t leaf_idx, uint32_t idx_offset, + const unsigned char *auth_path, uint32_t tree_height, + const spx_ctx *ctx, uint32_t addr[8]); + +/** + * For a given leaf index, computes the authentication path and the resulting + * root node using Merkle's TreeHash algorithm. + * Expects the layer and tree parts of the tree_addr to be set, as well as the + * tree type (i.e. SPX_ADDR_TYPE_HASHTREE or SPX_ADDR_TYPE_FORSTREE). + * Applies the offset idx_offset to indices before building addresses, so that + * it is possible to continue counting indices across trees. + */ +#define treehash SPX_NAMESPACE(treehash) +void treehash(unsigned char *root, unsigned char *auth_path, + const spx_ctx* ctx, + uint32_t leaf_idx, uint32_t idx_offset, uint32_t tree_height, + void (*gen_leaf)( + unsigned char* /* leaf */, + const spx_ctx* ctx /* ctx */, + uint32_t /* addr_idx */, const uint32_t[8] /* tree_addr */), + uint32_t tree_addr[8]); + + +#endif diff --git a/Blastproof/initfsgen/utilsx1.c b/Blastproof/common_crypto/utilsx1.c similarity index 100% rename from Blastproof/initfsgen/utilsx1.c rename to Blastproof/common_crypto/utilsx1.c diff --git a/Blastproof/common_crypto/utilsx1.h b/Blastproof/common_crypto/utilsx1.h new file mode 100644 index 0000000..a7fcf15 --- /dev/null +++ b/Blastproof/common_crypto/utilsx1.h @@ -0,0 +1,26 @@ +#ifndef SPX_UTILSX4_H +#define SPX_UTILSX4_H + +#include +#include "params.h" +#include "context.h" + +/** + * For a given leaf index, computes the authentication path and the resulting + * root node using Merkle's TreeHash algorithm. + * Expects the layer and tree parts of the tree_addr to be set, as well as the + * tree type (i.e. SPX_ADDR_TYPE_HASHTREE or SPX_ADDR_TYPE_FORSTREE). + * Applies the offset idx_offset to indices before building addresses, so that + * it is possible to continue counting indices across trees. + */ +#define treehashx1 SPX_NAMESPACE(treehashx1) +void treehashx1(unsigned char *root, unsigned char *auth_path, + const spx_ctx* ctx, + uint32_t leaf_idx, uint32_t idx_offset, uint32_t tree_height, + void (*gen_leaf)( + unsigned char* /* Where to write the leaf */, + const spx_ctx* /* ctx */, + uint32_t addr_idx, void *info), + uint32_t tree_addrx4[8], void *info); + +#endif diff --git a/Blastproof/initfsgen/wots.c b/Blastproof/common_crypto/wots.c similarity index 100% rename from Blastproof/initfsgen/wots.c rename to Blastproof/common_crypto/wots.c diff --git a/Blastproof/common_crypto/wots.h b/Blastproof/common_crypto/wots.h new file mode 100644 index 0000000..7e77056 --- /dev/null +++ b/Blastproof/common_crypto/wots.h @@ -0,0 +1,25 @@ +#ifndef SPX_WOTS_H +#define SPX_WOTS_H + +#include + +#include "params.h" +#include "context.h" + +/** + * Takes a WOTS signature and an n-byte message, computes a WOTS public key. + * + * Writes the computed public key to 'pk'. + */ +#define wots_pk_from_sig SPX_NAMESPACE(wots_pk_from_sig) +void wots_pk_from_sig(unsigned char *pk, + const unsigned char *sig, const unsigned char *msg, + const spx_ctx *ctx, uint32_t addr[8]); + +/* + * Compute the chain lengths needed for a given message hash + */ +#define chain_lengths SPX_NAMESPACE(chain_lengths) +void chain_lengths(unsigned int *lengths, const unsigned char *msg); + +#endif diff --git a/Blastproof/initfsgen/wotsx1.c b/Blastproof/common_crypto/wotsx1.c similarity index 100% rename from Blastproof/initfsgen/wotsx1.c rename to Blastproof/common_crypto/wotsx1.c diff --git a/Blastproof/common_crypto/wotsx1.h b/Blastproof/common_crypto/wotsx1.h new file mode 100644 index 0000000..1257f81 --- /dev/null +++ b/Blastproof/common_crypto/wotsx1.h @@ -0,0 +1,36 @@ +#if !defined( WOTSX1_H_ ) +#define WOTSX1_H_ + +#include + +/* + * This is here to provide an interface to the internal wots_gen_leafx1 + * routine. While this routine is not referenced in the package outside of + * wots.c, it is called from the stand-alone benchmark code to characterize + * the performance + */ +struct leaf_info_x1 { + unsigned char *wots_sig; + uint32_t wots_sign_leaf; /* The index of the WOTS we're using to sign */ + uint32_t *wots_steps; + uint32_t leaf_addr[8]; + uint32_t pk_addr[8]; +}; + +/* Macro to set the leaf_info to something 'benign', that is, it would */ +/* run with the same time as it does during the real signing process */ +/* Used only by the benchmark code */ +#define INITIALIZE_LEAF_INFO_X1(info, addr, step_buffer) { \ + info.wots_sig = 0; \ + info.wots_sign_leaf = ~0u; \ + info.wots_steps = step_buffer; \ + memcpy( &info.leaf_addr[0], addr, 32 ); \ + memcpy( &info.pk_addr[0], addr, 32 ); \ +} + +#define wots_gen_leafx1 SPX_NAMESPACE(wots_gen_leafx1) +void wots_gen_leafx1(unsigned char *dest, + const spx_ctx *ctx, + uint32_t leaf_idx, void *v_info); + +#endif /* WOTSX1_H_ */ diff --git a/Blastproof/config/bp_template.conf b/Blastproof/config/bp_template.cfg similarity index 91% rename from Blastproof/config/bp_template.conf rename to Blastproof/config/bp_template.cfg index 6cb8088..f4f18d9 100644 --- a/Blastproof/config/bp_template.conf +++ b/Blastproof/config/bp_template.cfg @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: MPL-2.0 # Blastproof config # WARNING : DO NOT PUT ANY NON-ASCII CHAR IN THIS FILE @@ -11,7 +12,7 @@ serial_port_erroring=true # Graphics # Define the font to use -font=bitra-ascii-medium.fbm +font=FONT.FBM # Define whether or not the boot animation should be played disable_boot_animation=true # Set the following both to 0 use highest resolution available @@ -46,3 +47,5 @@ kernel_log_disable_serial_port=false kernel_disable_serial_port=false # Define the size of the ring buffer for logging information. Value is in 4KB pages, ranging from 0 (ring logging disabled) to 65535 kernel_log_ring_size=2048 +# Define the amount of keyboards events each keyboard events queue can hold (ranging from 64 to 65535) +kernel_kbd_events_queue_capacity=256 diff --git a/Blastproof/config/config.json b/Blastproof/config/config.json new file mode 100644 index 0000000..0376339 --- /dev/null +++ b/Blastproof/config/config.json @@ -0,0 +1,24 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Blastproof configuration patching", + "actions":[ + { + "action":"run_command_wait", + "args":{ + "command_variables":true, + "command":[ + "./config_patch.sh", + "$INITFS_UNIQUE_UUID$", + "$SIGNSYST_UNIQUE_UUID$" + ], + "show_output":"on_failure", + "success_status":[ + 0 + ], + "ignore_success_status":false + } + } + ] +} diff --git a/Blastproof/config/config_patch.sh b/Blastproof/config/config_patch.sh new file mode 100755 index 0000000..cba8297 --- /dev/null +++ b/Blastproof/config/config_patch.sh @@ -0,0 +1,8 @@ +rm -f bp.conf +INITFS_TYPE_GUID="8362b434-d825-11f0-a68f-10ffe08423a6" +SIGNSYST_TYPE_GUID="da0048b4-d826-11f0-b877-10ffe08423a6" +INITFS_GUID=$1 +SIGNSYST_GUID=$2 +cp bp_template.cfg bp.cfg +sed -i -E "s/=(UUID_GENERATION_NEEDED_INITFS)/=$INITFS_GUID/" bp.cfg +sed -i -E "s/=(UUID_GENERATION_NEEDED_SIGNSYST)/=$SIGNSYST_GUID/" bp.cfg diff --git a/Blastproof/edk2.json b/Blastproof/edk2.json new file mode 100644 index 0000000..51f48c5 --- /dev/null +++ b/Blastproof/edk2.json @@ -0,0 +1,81 @@ +{ + "version":"0.1", + "root_folder":"%rootcallerfolder%", + "run_context":"sub", + "name":"EDK2 setup", + "actions":[ + { + "action":"run_command_wait", + "args":{ + "command_variables":false, + "command":[ + "git", + "clone", + "https://github.com/tianocore/edk2.git" + ], + "show_output":"live", + "success_status":[ + 0 + ], + "ignore_success_status":false + } + }, + { + "action":"run_command_wait_dir", + "args":{ + "command_variables":false, + "command":[ + "git", + "submodule", + "update", + "--init", + "--recursive", + "--progress" + ], + "show_output":"live", + "success_status":[ + 0 + ], + "ignore_success_status":false, + "working_dir_variables":true, + "working_dir":"%rootcallerfolder%/$EDK2_DIR$" + } + }, + { + "action":"run_command_wait_dir", + "args":{ + "command_variables":false, + "command":[ + "make", + "-C", + "BaseTools/" + ], + "show_output":"live", + "success_status":[ + 0 + ], + "ignore_success_status":false, + "working_dir_variables":true, + "working_dir":"%rootcallerfolder%/$EDK2_DIR$" + } + }, + { + "action":"run_command_wait_dir", + "args":{ + "command_variables":false, + "command":[ + "bash", + "-c", + "../Blastproof/ovmf.sh" + ], + "show_output":"live", + "success_status":[ + 0 + ], + "ignore_success_status":false, + "working_dir_variables":true, + "working_dir":"%rootcallerfolder%/$EDK2_DIR$" + } + } + ] +} diff --git a/Blastproof/fontgen/fontgen.json b/Blastproof/fontgen/fontgen.json new file mode 100644 index 0000000..dc366e3 --- /dev/null +++ b/Blastproof/fontgen/fontgen.json @@ -0,0 +1,92 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Fontgen build", + "actions":[ + { + "action":"compile_one_cpp", + "args":{ + "source_variables":false, + "source":"fontgen.cpp", + "compiler_variables":true, + "compiler":"$CPP_COMPILER$", + "pre_arguments_variables":true, + "pre_arguments":[ + ], + "post_arguments_variables":true, + "post_arguments":[ + "-o", + "$FONTGEN_BINARY_NAME$" + ], + "output_file_variables":true, + "output_file":"$FONTGEN_BINARY_NAME$", + "success_status":[ + 0 + ], + "ignore_success_status":true, + "cache_authorized":true, + "headers_command_variables":true, + "headers_command":"gcc -MMD -MF %dfile% -E %sourcefile% -o /dev/null" + } + }, + { + "action":"run_actions_if", + "args":{ + "condition":{ + "condition_variables":false, + "condition":"cache_contains", + "condition_args_variables":false, + "condition_args":[ + "font.fbm" + ] + }, + "actions":[ + { + "action":"extract_from_cache", + "args":{ + "target_variables":false, + "target":"font.fbm", + "output_file_variables":true, + "output_file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/fontgen/font.fbm" + } + }, + { + "action":"exit_current_module", + "args":{ + "is_fail":false + } + } + ] + } + }, + { + "action":"run_command_wait", + "args":{ + "command_variables":true, + "command":[ + "./fontgen", + "#FFFFFF", + "#000000", + "ascii", + "./chars" + ], + "show_output":"on_failure", + "success_status":[ + 0 + ], + "ignore_success_status":false + } + }, + { + "action":"store_in_cache", + "args":{ + "key_variables":false, + "key":"font.fbm", + "file_variables":true, + "file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/fontgen/font.fbm", + "overwrite_allowed":false + } + } + ] +} diff --git a/Blastproof/initfsgen/initfsgen.cpp b/Blastproof/initfsgen/initfsgen.cpp index 8473592..5d54ff0 100644 --- a/Blastproof/initfsgen/initfsgen.cpp +++ b/Blastproof/initfsgen/initfsgen.cpp @@ -12,14 +12,15 @@ extern "C" { #include #include #include +#include "common/versions.h" using namespace std; namespace fs=filesystem; #pragma pack(push,1) struct initfs_header { uint8_t sign[8]={'I','n','i','t','F','i','S','y'}; - uint16_t bootloader_version=0x0001; - uint16_t initfs_version=0x0001; - uint32_t os_version=0x00000001; + uint16_t bootloader_version=VY_COMMON_VERSIONS_BOOTLOADER; + uint16_t initfs_version=VY_COMMON_VERSIONS_INITFS; + uint32_t os_version=VY_COMMON_VERSIONS_OS; uint8_t installation_id[48]={0}; uint64_t initfs_size=0; uint64_t table_size=0; @@ -48,9 +49,9 @@ struct file_entry { #pragma pack(push,1) struct signsyst_header { uint8_t sign[8]={'S','i','g','n','S','y','s','t'}; - uint16_t bootloader_version=0x0001; - uint16_t initfs_version=0x0001; - uint32_t os_version=0x00000001; + uint16_t bootloader_version=VY_COMMON_VERSIONS_BOOTLOADER; + uint16_t initfs_version=VY_COMMON_VERSIONS_INITFS; + uint32_t os_version=VY_COMMON_VERSIONS_OS; uint8_t installation_id[48]={0}; uint64_t signature_size=0; uint64_t signature_count=0; @@ -138,7 +139,7 @@ int main(int argc,char **argv) { uint64_t value=(header.initfs_size+header.table_size+header.files_area_size+header.entries_width+header.entries_count+header.files_area_offset)%UINT64_MAX; header.check1=(value*0x9E3779B185EBCA87)^header.entropy_check1; sha3(header.installation_id,sizeof(header.installation_id),header.installation_id_hash_hash,sizeof(header.installation_id_hash_hash)); - ofstream initfs_footprint("initfs-footprint.bin",ios::binary); + ofstream initfs_footprint("initfsfp.bin",ios::binary); if (!initfs_footprint) { cout<<"[InitFSGen] Error: Can't open initfs-footprint.bin."<(entries_table.data()),entries_table.size()); initfs_bin.write(reinterpret_cast(files_area.data()),files_area.size()); initfs_bin.close(); - ofstream signsyst_hash("signsyst-hash.bin",ios::binary); + ofstream signsyst_hash("sshash.bin",ios::binary); if (!signsyst_hash) { cout<<"[InitFSGen] Error: Can't open signsyst-hash.bin."< -#include - -#include "address.h" -#include "params.h" -#include "utils.h" - -/* - * Specify which level of Merkle tree (the "layer") we're working on - */ -void set_layer_addr(uint32_t addr[8], uint32_t layer) -{ - ((unsigned char *)addr)[SPX_OFFSET_LAYER] = (unsigned char)layer; -} - -/* - * Specify which Merkle tree within the level (the "tree address") we're working on - */ -void set_tree_addr(uint32_t addr[8], uint64_t tree) -{ -#if (SPX_TREE_HEIGHT * (SPX_D - 1)) > 64 - #error Subtree addressing is currently limited to at most 2^64 trees -#endif - ull_to_bytes(&((unsigned char *)addr)[SPX_OFFSET_TREE], 8, tree ); -} - -/* - * Specify the reason we'll use this address structure for, that is, what - * hash will we compute with it. This is used so that unrelated types of - * hashes don't accidentally get the same address structure. The type will be - * one of the SPX_ADDR_TYPE constants - */ -void set_type(uint32_t addr[8], uint32_t type) -{ - ((unsigned char *)addr)[SPX_OFFSET_TYPE] = (unsigned char)type; -} - -/* - * Copy the layer and tree fields of the address structure. This is used - * when we're doing multiple types of hashes within the same Merkle tree - */ -void copy_subtree_addr(uint32_t out[8], const uint32_t in[8]) -{ - memcpy( out, in, SPX_OFFSET_TREE+8 ); -} - -/* These functions are used for OTS addresses. */ - -/* - * Specify which Merkle leaf we're working on; that is, which OTS keypair - * we're talking about. - */ -void set_keypair_addr(uint32_t addr[8], uint32_t keypair) -{ - u32_to_bytes(&((unsigned char *)addr)[SPX_OFFSET_KP_ADDR], keypair); -} - -/* - * Copy the layer, tree and keypair fields of the address structure. This is - * used when we're doing multiple things within the same OTS keypair - */ -void copy_keypair_addr(uint32_t out[8], const uint32_t in[8]) -{ - memcpy( out, in, SPX_OFFSET_TREE+8 ); - memcpy( (unsigned char *)out + SPX_OFFSET_KP_ADDR, (unsigned char *)in + SPX_OFFSET_KP_ADDR, 4); -} - -/* - * Specify which Merkle chain within the OTS we're working with - * (the chain address) - */ -void set_chain_addr(uint32_t addr[8], uint32_t chain) -{ - ((unsigned char *)addr)[SPX_OFFSET_CHAIN_ADDR] = (unsigned char)chain; -} - -/* - * Specify where in the Merkle chain we are -* (the hash address) - */ -void set_hash_addr(uint32_t addr[8], uint32_t hash) -{ - ((unsigned char *)addr)[SPX_OFFSET_HASH_ADDR] = (unsigned char)hash; -} - -/* These functions are used for all hash tree addresses (including FORS). */ - -/* - * Specify the height of the node in the Merkle/FORS tree we are in - * (the tree height) - */ -void set_tree_height(uint32_t addr[8], uint32_t tree_height) -{ - ((unsigned char *)addr)[SPX_OFFSET_TREE_HGT] = (unsigned char)tree_height; -} - -/* - * Specify the distance from the left edge of the node in the Merkle/FORS tree - * (the tree index) - */ -void set_tree_index(uint32_t addr[8], uint32_t tree_index) -{ - u32_to_bytes(&((unsigned char *)addr)[SPX_OFFSET_TREE_INDEX], tree_index ); -} diff --git a/Blastproof/keygen/address.o b/Blastproof/keygen/address.o deleted file mode 100644 index 5f348fe..0000000 Binary files a/Blastproof/keygen/address.o and /dev/null differ diff --git a/Blastproof/keygen/argon2/Argon2.sln b/Blastproof/keygen/argon2/Argon2.sln deleted file mode 100644 index b16cda0..0000000 --- a/Blastproof/keygen/argon2/Argon2.sln +++ /dev/null @@ -1,158 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2OptTestCI", "vs2015\Argon2OptTestCI\Argon2OptTestCI.vcxproj", "{12956597-5E42-433A-93F3-D4EFF50AA207}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2RefTestCI", "vs2015\Argon2RefTestCI\Argon2RefTestCI.vcxproj", "{8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2OptGenKAT", "vs2015\Argon2OptGenKAT\Argon2OptGenKAT.vcxproj", "{DBBAAAE6-4560-4D11-8280-30A6650A82EF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2RefGenKAT", "vs2015\Argon2RefGenKAT\Argon2RefGenKAT.vcxproj", "{71921B4C-A795-4A37-95A3-99D600E01211}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2Opt", "vs2015\Argon2Opt\Argon2Opt.vcxproj", "{CAA75C57-998C-494E-B8A5-5894EF0FC528}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2Ref", "vs2015\Argon2Ref\Argon2Ref.vcxproj", "{B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2OptBench", "vs2015\Argon2OptBench\Argon2OptBench.vcxproj", "{B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2RefBench", "vs2015\Argon2RefBench\Argon2RefBench.vcxproj", "{99203F6A-6E8C-42FC-8C7C-C07E8913D539}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2OptDll", "vs2015\Argon2OptDll\Argon2OptDll.vcxproj", "{3A898DD8-ACAE-4269-ADFE-EB7260D71583}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Argon2RefDll", "vs2015\Argon2RefDll\Argon2RefDll.vcxproj", "{19D911A1-533C-4475-B313-F372481A35D4}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - ReleaseStatic|x64 = ReleaseStatic|x64 - ReleaseStatic|x86 = ReleaseStatic|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {12956597-5E42-433A-93F3-D4EFF50AA207}.Debug|x64.ActiveCfg = Debug|x64 - {12956597-5E42-433A-93F3-D4EFF50AA207}.Debug|x64.Build.0 = Debug|x64 - {12956597-5E42-433A-93F3-D4EFF50AA207}.Debug|x86.ActiveCfg = Debug|Win32 - {12956597-5E42-433A-93F3-D4EFF50AA207}.Debug|x86.Build.0 = Debug|Win32 - {12956597-5E42-433A-93F3-D4EFF50AA207}.Release|x64.ActiveCfg = Release|x64 - {12956597-5E42-433A-93F3-D4EFF50AA207}.Release|x64.Build.0 = Release|x64 - {12956597-5E42-433A-93F3-D4EFF50AA207}.Release|x86.ActiveCfg = Release|Win32 - {12956597-5E42-433A-93F3-D4EFF50AA207}.Release|x86.Build.0 = Release|Win32 - {12956597-5E42-433A-93F3-D4EFF50AA207}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {12956597-5E42-433A-93F3-D4EFF50AA207}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {12956597-5E42-433A-93F3-D4EFF50AA207}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {12956597-5E42-433A-93F3-D4EFF50AA207}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.Debug|x64.ActiveCfg = Debug|x64 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.Debug|x64.Build.0 = Debug|x64 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.Debug|x86.ActiveCfg = Debug|Win32 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.Debug|x86.Build.0 = Debug|Win32 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.Release|x64.ActiveCfg = Release|x64 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.Release|x64.Build.0 = Release|x64 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.Release|x86.ActiveCfg = Release|Win32 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.Release|x86.Build.0 = Release|Win32 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.Debug|x64.ActiveCfg = Debug|x64 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.Debug|x64.Build.0 = Debug|x64 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.Debug|x86.ActiveCfg = Debug|Win32 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.Debug|x86.Build.0 = Debug|Win32 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.Release|x64.ActiveCfg = Release|x64 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.Release|x64.Build.0 = Release|x64 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.Release|x86.ActiveCfg = Release|Win32 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.Release|x86.Build.0 = Release|Win32 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {DBBAAAE6-4560-4D11-8280-30A6650A82EF}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {71921B4C-A795-4A37-95A3-99D600E01211}.Debug|x64.ActiveCfg = Debug|x64 - {71921B4C-A795-4A37-95A3-99D600E01211}.Debug|x64.Build.0 = Debug|x64 - {71921B4C-A795-4A37-95A3-99D600E01211}.Debug|x86.ActiveCfg = Debug|Win32 - {71921B4C-A795-4A37-95A3-99D600E01211}.Debug|x86.Build.0 = Debug|Win32 - {71921B4C-A795-4A37-95A3-99D600E01211}.Release|x64.ActiveCfg = Release|x64 - {71921B4C-A795-4A37-95A3-99D600E01211}.Release|x64.Build.0 = Release|x64 - {71921B4C-A795-4A37-95A3-99D600E01211}.Release|x86.ActiveCfg = Release|Win32 - {71921B4C-A795-4A37-95A3-99D600E01211}.Release|x86.Build.0 = Release|Win32 - {71921B4C-A795-4A37-95A3-99D600E01211}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {71921B4C-A795-4A37-95A3-99D600E01211}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {71921B4C-A795-4A37-95A3-99D600E01211}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {71921B4C-A795-4A37-95A3-99D600E01211}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.Debug|x64.ActiveCfg = Debug|x64 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.Debug|x64.Build.0 = Debug|x64 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.Debug|x86.ActiveCfg = Debug|Win32 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.Debug|x86.Build.0 = Debug|Win32 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.Release|x64.ActiveCfg = Release|x64 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.Release|x64.Build.0 = Release|x64 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.Release|x86.ActiveCfg = Release|Win32 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.Release|x86.Build.0 = Release|Win32 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {CAA75C57-998C-494E-B8A5-5894EF0FC528}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x64.ActiveCfg = Debug|x64 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x64.Build.0 = Debug|x64 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x86.ActiveCfg = Debug|Win32 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Debug|x86.Build.0 = Debug|Win32 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x64.ActiveCfg = Release|x64 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x64.Build.0 = Release|x64 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x86.ActiveCfg = Release|Win32 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.Release|x86.Build.0 = Release|Win32 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.Debug|x64.ActiveCfg = Debug|x64 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.Debug|x64.Build.0 = Debug|x64 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.Debug|x86.ActiveCfg = Debug|Win32 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.Debug|x86.Build.0 = Debug|Win32 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.Release|x64.ActiveCfg = Release|x64 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.Release|x64.Build.0 = Release|x64 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.Release|x86.ActiveCfg = Release|Win32 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.Release|x86.Build.0 = Release|Win32 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.Debug|x64.ActiveCfg = Debug|x64 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.Debug|x64.Build.0 = Debug|x64 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.Debug|x86.ActiveCfg = Debug|Win32 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.Debug|x86.Build.0 = Debug|Win32 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.Release|x64.ActiveCfg = Release|x64 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.Release|x64.Build.0 = Release|x64 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.Release|x86.ActiveCfg = Release|Win32 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.Release|x86.Build.0 = Release|Win32 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {99203F6A-6E8C-42FC-8C7C-C07E8913D539}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.Debug|x64.ActiveCfg = Debug|x64 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.Debug|x64.Build.0 = Debug|x64 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.Debug|x86.ActiveCfg = Debug|Win32 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.Debug|x86.Build.0 = Debug|Win32 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.Release|x64.ActiveCfg = Release|x64 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.Release|x64.Build.0 = Release|x64 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.Release|x86.ActiveCfg = Release|Win32 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.Release|x86.Build.0 = Release|Win32 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {3A898DD8-ACAE-4269-ADFE-EB7260D71583}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - {19D911A1-533C-4475-B313-F372481A35D4}.Debug|x64.ActiveCfg = Debug|x64 - {19D911A1-533C-4475-B313-F372481A35D4}.Debug|x64.Build.0 = Debug|x64 - {19D911A1-533C-4475-B313-F372481A35D4}.Debug|x86.ActiveCfg = Debug|Win32 - {19D911A1-533C-4475-B313-F372481A35D4}.Debug|x86.Build.0 = Debug|Win32 - {19D911A1-533C-4475-B313-F372481A35D4}.Release|x64.ActiveCfg = Release|x64 - {19D911A1-533C-4475-B313-F372481A35D4}.Release|x64.Build.0 = Release|x64 - {19D911A1-533C-4475-B313-F372481A35D4}.Release|x86.ActiveCfg = Release|Win32 - {19D911A1-533C-4475-B313-F372481A35D4}.Release|x86.Build.0 = Release|Win32 - {19D911A1-533C-4475-B313-F372481A35D4}.ReleaseStatic|x64.ActiveCfg = ReleaseStatic|x64 - {19D911A1-533C-4475-B313-F372481A35D4}.ReleaseStatic|x64.Build.0 = ReleaseStatic|x64 - {19D911A1-533C-4475-B313-F372481A35D4}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Win32 - {19D911A1-533C-4475-B313-F372481A35D4}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Blastproof/keygen/argon2/CHANGELOG.md b/Blastproof/keygen/argon2/CHANGELOG.md deleted file mode 100644 index 0578fde..0000000 --- a/Blastproof/keygen/argon2/CHANGELOG.md +++ /dev/null @@ -1,32 +0,0 @@ -# 20171227 -* Added ABI version number -* AVX2/AVX-512F optimizations of BLAMKA -* Set Argon2 version number from the command line -* New bindings -* Minor bug and warning fixes (no security issue) - -# 20161029 - -* Argon2id added -* Better documentation -* Dual licensing CC0 / Apache 2.0 -* Minor bug fixes (no security issue) - -# 20160406 - -* Version 1.3 of Argon2 -* Version number in encoded hash -* Refactored low-level API -* Visibility control for library symbols -* Microsoft Visual Studio solution -* New bindings -* Minor bug and warning fixes (no security issue) - - -# 20151206 - -* Python bindings -* Password read from stdin, instead of being an argument -* Compatibility FreeBSD, NetBSD, OpenBSD -* Constant-time verification -* Minor bug and warning fixes (no security issue) diff --git a/Blastproof/keygen/argon2/LICENSE b/Blastproof/keygen/argon2/LICENSE deleted file mode 100644 index a16d6d2..0000000 --- a/Blastproof/keygen/argon2/LICENSE +++ /dev/null @@ -1,314 +0,0 @@ -Argon2 reference source code package - reference C implementations - -Copyright 2015 -Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - -You may use this work under the terms of a Creative Commons CC0 1.0 -License/Waiver or the Apache Public License 2.0, at your option. The terms of -these licenses can be found at: - -- CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 -- Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - -The terms of the licenses are reproduced below. - --------------------------------------------------------------------------------- - -Creative Commons Legal Code - -CC0 1.0 Universal - - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS - INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES - REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS - PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED - HEREUNDER. - -Statement of Purpose - -The laws of most jurisdictions throughout the world automatically confer -exclusive Copyright and Related Rights (defined below) upon the creator -and subsequent owner(s) (each and all, an "owner") of an original work of -authorship and/or a database (each, a "Work"). - -Certain owners wish to permanently relinquish those rights to a Work for -the purpose of contributing to a commons of creative, cultural and -scientific works ("Commons") that the public can reliably and without fear -of later claims of infringement build upon, modify, incorporate in other -works, reuse and redistribute as freely as possible in any form whatsoever -and for any purposes, including without limitation commercial purposes. -These owners may contribute to the Commons to promote the ideal of a free -culture and the further production of creative, cultural and scientific -works, or to gain reputation or greater distribution for their Work in -part through the use and efforts of others. - -For these and/or other purposes and motivations, and without any -expectation of additional consideration or compensation, the person -associating CC0 with a Work (the "Affirmer"), to the extent that he or she -is an owner of Copyright and Related Rights in the Work, voluntarily -elects to apply CC0 to the Work and publicly distribute the Work under its -terms, with knowledge of his or her Copyright and Related Rights in the -Work and the meaning and intended legal effect of CC0 on those rights. - -1. Copyright and Related Rights. A Work made available under CC0 may be -protected by copyright and related or neighboring rights ("Copyright and -Related Rights"). Copyright and Related Rights include, but are not -limited to, the following: - - i. the right to reproduce, adapt, distribute, perform, display, - communicate, and translate a Work; - ii. moral rights retained by the original author(s) and/or performer(s); -iii. publicity and privacy rights pertaining to a person's image or - likeness depicted in a Work; - iv. rights protecting against unfair competition in regards to a Work, - subject to the limitations in paragraph 4(a), below; - v. rights protecting the extraction, dissemination, use and reuse of data - in a Work; - vi. database rights (such as those arising under Directive 96/9/EC of the - European Parliament and of the Council of 11 March 1996 on the legal - protection of databases, and under any national implementation - thereof, including any amended or successor version of such - directive); and -vii. other similar, equivalent or corresponding rights throughout the - world based on applicable law or treaty, and any national - implementations thereof. - -2. Waiver. To the greatest extent permitted by, but not in contravention -of, applicable law, Affirmer hereby overtly, fully, permanently, -irrevocably and unconditionally waives, abandons, and surrenders all of -Affirmer's Copyright and Related Rights and associated claims and causes -of action, whether now known or unknown (including existing as well as -future claims and causes of action), in the Work (i) in all territories -worldwide, (ii) for the maximum duration provided by applicable law or -treaty (including future time extensions), (iii) in any current or future -medium and for any number of copies, and (iv) for any purpose whatsoever, -including without limitation commercial, advertising or promotional -purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each -member of the public at large and to the detriment of Affirmer's heirs and -successors, fully intending that such Waiver shall not be subject to -revocation, rescission, cancellation, termination, or any other legal or -equitable action to disrupt the quiet enjoyment of the Work by the public -as contemplated by Affirmer's express Statement of Purpose. - -3. Public License Fallback. Should any part of the Waiver for any reason -be judged legally invalid or ineffective under applicable law, then the -Waiver shall be preserved to the maximum extent permitted taking into -account Affirmer's express Statement of Purpose. In addition, to the -extent the Waiver is so judged Affirmer hereby grants to each affected -person a royalty-free, non transferable, non sublicensable, non exclusive, -irrevocable and unconditional license to exercise Affirmer's Copyright and -Related Rights in the Work (i) in all territories worldwide, (ii) for the -maximum duration provided by applicable law or treaty (including future -time extensions), (iii) in any current or future medium and for any number -of copies, and (iv) for any purpose whatsoever, including without -limitation commercial, advertising or promotional purposes (the -"License"). The License shall be deemed effective as of the date CC0 was -applied by Affirmer to the Work. Should any part of the License for any -reason be judged legally invalid or ineffective under applicable law, such -partial invalidity or ineffectiveness shall not invalidate the remainder -of the License, and in such case Affirmer hereby affirms that he or she -will not (i) exercise any of his or her remaining Copyright and Related -Rights in the Work or (ii) assert any associated claims and causes of -action with respect to the Work, in either case contrary to Affirmer's -express Statement of Purpose. - -4. Limitations and Disclaimers. - - a. No trademark or patent rights held by Affirmer are waived, abandoned, - surrendered, licensed or otherwise affected by this document. - b. Affirmer offers the Work as-is and makes no representations or - warranties of any kind concerning the Work, express, implied, - statutory or otherwise, including without limitation warranties of - title, merchantability, fitness for a particular purpose, non - infringement, or the absence of latent or other defects, accuracy, or - the present or absence of errors, whether or not discoverable, all to - the greatest extent permissible under applicable law. - c. Affirmer disclaims responsibility for clearing rights of other persons - that may apply to the Work or any use thereof, including without - limitation any person's Copyright and Related Rights in the Work. - Further, Affirmer disclaims responsibility for obtaining any necessary - consents, permissions or other rights required for any use of the - Work. - d. Affirmer understands and acknowledges that Creative Commons is not a - party to this document and has no duty or obligation with respect to - this CC0 or use of the Work. - --------------------------------------------------------------------------------- - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/Blastproof/keygen/argon2/Makefile b/Blastproof/keygen/argon2/Makefile deleted file mode 100644 index 44c076a..0000000 --- a/Blastproof/keygen/argon2/Makefile +++ /dev/null @@ -1,255 +0,0 @@ -# -# Argon2 reference source code package - reference C implementations -# -# Copyright 2015 -# Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves -# -# You may use this work under the terms of a Creative Commons CC0 1.0 -# License/Waiver or the Apache Public License 2.0, at your option. The terms of -# these licenses can be found at: -# -# - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 -# - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 -# -# You should have received a copy of both of these licenses along with this -# software. If not, they may be obtained at the above URLs. -# - -RUN = argon2 -BENCH = bench -GENKAT = genkat -ARGON2_VERSION ?= ZERO - -# installation parameters for staging area and final installation path -# Note; if Linux and not Debian/Ubuntu version also add lib override to make command-line -# for RedHat/Fedora, add: LIBRARY_REL=lib64 -DESTDIR ?= -PREFIX ?= /usr - -# Increment on an ABI breaking change -ABI_VERSION = 1 - -DIST = phc-winner-argon2 - -SRC = src/argon2.c src/core.c src/blake2/blake2b.c src/thread.c src/encoding.c -SRC_RUN = src/run.c -SRC_BENCH = src/bench.c -SRC_GENKAT = src/genkat.c -OBJ = $(SRC:.c=.o) - -CFLAGS += -std=c89 -O3 -Wall -g -Iinclude -Isrc - -ifeq ($(NO_THREADS), 1) -CFLAGS += -DARGON2_NO_THREADS -else -CFLAGS += -pthread -endif - -CI_CFLAGS := $(CFLAGS) -Werror=declaration-after-statement -D_FORTIFY_SOURCE=2 \ - -Wextra -Wno-type-limits -Werror -coverage -DTEST_LARGE_RAM - -OPTTARGET ?= native -OPTTEST := $(shell $(CC) -Iinclude -Isrc -march=$(OPTTARGET) src/opt.c -c \ - -o /dev/null 2>/dev/null; echo $$?) -# Detect compatible platform -ifneq ($(OPTTEST), 0) -$(info Building without optimizations) - SRC += src/ref.c -else -$(info Building with optimizations for $(OPTTARGET)) - CFLAGS += -march=$(OPTTARGET) - SRC += src/opt.c -endif - -BUILD_PATH := $(shell pwd) -KERNEL_NAME := $(shell uname -s) -MACHINE_NAME := $(shell uname -m) - -LIB_NAME = argon2 -PC_NAME = lib$(LIB_NAME).pc -PC_SRC = $(PC_NAME).in - -ifeq ($(KERNEL_NAME), Linux) - LIB_EXT := so.$(ABI_VERSION) - LIB_CFLAGS := -shared -fPIC -fvisibility=hidden -DA2_VISCTL=1 - SO_LDFLAGS := -Wl,-soname,lib$(LIB_NAME).$(LIB_EXT) - LINKED_LIB_EXT := so - PC_EXTRA_LIBS ?= -lrt -ldl -endif -ifeq ($(KERNEL_NAME), $(filter $(KERNEL_NAME),DragonFly FreeBSD NetBSD OpenBSD)) - LIB_EXT := so - LIB_CFLAGS := -shared -fPIC - PC_EXTRA_LIBS ?= -endif -ifeq ($(KERNEL_NAME), Darwin) - LIB_EXT := $(ABI_VERSION).dylib - LIB_CFLAGS = -dynamiclib -install_name $(PREFIX)/$(LIBRARY_REL)/lib$(LIB_NAME).$(LIB_EXT) - LINKED_LIB_EXT := dylib - PC_EXTRA_LIBS ?= -endif -ifeq ($(findstring CYGWIN, $(KERNEL_NAME)), CYGWIN) - LIB_EXT := dll - LIB_CFLAGS := -shared -Wl,--out-implib,lib$(LIB_NAME).$(LIB_EXT).a - PC_EXTRA_LIBS ?= -endif -ifeq ($(findstring MINGW, $(KERNEL_NAME)), MINGW) - LIB_EXT := dll - LIB_CFLAGS := -shared -Wl,--out-implib,lib$(LIB_NAME).$(LIB_EXT).a - PC_EXTRA_LIBS ?= -endif -ifeq ($(findstring MSYS, $(KERNEL_NAME)), MSYS) - LIB_EXT := dll - LIB_CFLAGS := -shared -Wl,--out-implib,lib$(LIB_NAME).$(LIB_EXT).a - PC_EXTRA_LIBS ?= -endif -ifeq ($(KERNEL_NAME), SunOS) - CC := gcc - CFLAGS += -D_REENTRANT - LIB_EXT := so - LIB_CFLAGS := -shared -fPIC - PC_EXTRA_LIBS ?= -endif - -ifeq ($(KERNEL_NAME), Linux) -ifeq ($(CC), clang) - CI_CFLAGS += -fsanitize=address -fsanitize=undefined -endif -endif - -LIB_SH := lib$(LIB_NAME).$(LIB_EXT) -LIB_ST := lib$(LIB_NAME).a - -ifdef LINKED_LIB_EXT -LINKED_LIB_SH := lib$(LIB_NAME).$(LINKED_LIB_EXT) -endif - -# Some systems don't provide an unprefixed ar when cross-compiling. -AR=ar - -LIBRARIES = $(LIB_SH) $(LIB_ST) -HEADERS = include/argon2.h - -INSTALL = install - -# relative paths for different OS -ifeq ($(KERNEL_NAME), $(filter $(KERNEL_NAME),DragonFly FreeBSD)) - -# default for FreeBSD -BINARY_REL ?= bin -INCLUDE_REL ?= include -LIBRARY_REL ?= lib -PKGCONFIG_REL ?= libdata - -else ifeq ($(KERNEL_NAME)-$(MACHINE_NAME), Linux-x86_64) - -# default for Debian/Ubuntu x86_64 -BINARY_REL ?= bin -INCLUDE_REL ?= include -LIBRARY_REL ?= lib/x86_64-linux-gnu -PKGCONFIG_REL ?= $(LIBRARY_REL) - -else - -# NetBSD, ... and Linux64/Linux32 variants that use plain lib directory -BINARY_REL ?= bin -INCLUDE_REL ?= include -LIBRARY_REL ?= lib -PKGCONFIG_REL ?= $(LIBRARY_REL) - -endif - -# absolute paths to staging area -INST_INCLUDE = $(DESTDIR)$(PREFIX)/$(INCLUDE_REL) -INST_LIBRARY = $(DESTDIR)$(PREFIX)/$(LIBRARY_REL) -INST_BINARY = $(DESTDIR)$(PREFIX)/$(BINARY_REL) -INST_PKGCONFIG = $(DESTDIR)$(PREFIX)/$(PKGCONFIG_REL)/pkgconfig - -# main target -.PHONY: all -all: $(RUN) libs - -.PHONY: libs -libs: $(LIBRARIES) $(PC_NAME) - -$(RUN): $(SRC) $(SRC_RUN) - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ - -$(BENCH): $(SRC) $(SRC_BENCH) - $(CC) $(CFLAGS) $^ -o $@ - -$(GENKAT): $(SRC) $(SRC_GENKAT) - $(CC) $(CFLAGS) $^ -o $@ -DGENKAT - -$(LIB_SH): $(SRC) - $(CC) $(CFLAGS) $(LIB_CFLAGS) $(LDFLAGS) $(SO_LDFLAGS) $^ -o $@ - -$(LIB_ST): $(OBJ) - $(AR) rcs $@ $^ - -.PHONY: clean -clean: - rm -f '$(RUN)' '$(BENCH)' '$(GENKAT)' - rm -f '$(LIB_SH)' '$(LIB_ST)' kat-argon2* '$(PC_NAME)' - rm -f testcase - rm -rf *.dSYM - cd src/ && rm -f *.o - cd src/blake2/ && rm -f *.o - cd kats/ && rm -f kat-* diff* run_* make_* - - -# all substitutions to pc template -SED_COMMANDS = /^\#\#.*$$/d; -SED_COMMANDS += s\#@PREFIX@\#$(PREFIX)\#g; -SED_COMMANDS += s\#@EXTRA_LIBS@\#$(PC_EXTRA_LIBS)\#g; -SED_COMMANDS += s\#@UPSTREAM_VER@\#$(ARGON2_VERSION)\#g; -SED_COMMANDS += s\#@HOST_MULTIARCH@\#$(LIBRARY_REL)\#g; -SED_COMMANDS += s\#@INCLUDE@\#$(INCLUDE_REL)\#g; - -# substitute PREFIX and PC_EXTRA_LIBS into pkgconfig pc file -$(PC_NAME): $(PC_SRC) - sed '$(SED_COMMANDS)' < '$(PC_SRC)' > '$@' - - -.PHONY: dist -dist: - cd ..; \ - tar -c --exclude='.??*' -z -f $(DIST)-`date "+%Y%m%d"`.tgz $(DIST)/* - -.PHONY: test -test: $(SRC) src/test.c - $(CC) $(CFLAGS) -Wextra -Wno-type-limits $^ -o testcase - @sh kats/test.sh - ./testcase - -.PHONY: testci -testci: $(SRC) src/test.c - $(CC) $(CI_CFLAGS) $^ -o testcase - @sh kats/test.sh - ./testcase - - -.PHONY: format -format: - clang-format -style="{BasedOnStyle: llvm, IndentWidth: 4}" \ - -i include/*.h src/*.c src/*.h src/blake2/*.c src/blake2/*.h - -.PHONY: install -install: $(RUN) libs - $(INSTALL) -d $(INST_INCLUDE) - $(INSTALL) -m 0644 $(HEADERS) $(INST_INCLUDE) - $(INSTALL) -d $(INST_LIBRARY) - $(INSTALL) -m 0644 $(LIBRARIES) $(INST_LIBRARY) -ifdef LINKED_LIB_SH - cd $(INST_LIBRARY) && ln -sf $(notdir $(LIB_SH) $(LINKED_LIB_SH)) -endif - $(INSTALL) -d $(INST_BINARY) - $(INSTALL) $(RUN) $(INST_BINARY) - $(INSTALL) -d $(INST_PKGCONFIG) - $(INSTALL) -m 0644 $(PC_NAME) $(INST_PKGCONFIG) - -.PHONY: uninstall -uninstall: - cd $(INST_INCLUDE) && rm -f $(notdir $(HEADERS)) - cd $(INST_LIBRARY) && rm -f $(notdir $(LIBRARIES) $(LINKED_LIB_SH)) - cd $(INST_BINARY) && rm -f $(notdir $(RUN)) - cd $(INST_PKG_CONFIG) && rm -f $(notdir $(PC_NAME)) diff --git a/Blastproof/keygen/argon2/Package.swift b/Blastproof/keygen/argon2/Package.swift deleted file mode 100644 index d3d9c83..0000000 --- a/Blastproof/keygen/argon2/Package.swift +++ /dev/null @@ -1,46 +0,0 @@ -// swift-tools-version:5.3 - -import PackageDescription - -let package = Package( - name: "argon2", - products: [ - .library( - name: "argon2", - targets: ["argon2"]), - ], - targets: [ - .target( - name: "argon2", - path: ".", - exclude: [ - "kats", - "vs2015", - "latex", - "libargon2.pc.in", - "export.sh", - "appveyor.yml", - "Argon2.sln", - "argon2-specs.pdf", - "CHANGELOG.md", - "LICENSE", - "Makefile", - "man", - "README.md", - "src/bench.c", - "src/genkat.c", - "src/opt.c", - "src/run.c", - "src/test.c", - ], - sources: [ - "src/blake2/blake2b.c", - "src/argon2.c", - "src/core.c", - "src/encoding.c", - "src/ref.c", - "src/thread.c" - ] - ) - ] -) \ No newline at end of file diff --git a/Blastproof/keygen/argon2/README.md b/Blastproof/keygen/argon2/README.md deleted file mode 100644 index 91fc3fd..0000000 --- a/Blastproof/keygen/argon2/README.md +++ /dev/null @@ -1,303 +0,0 @@ -# Argon2 - -[![Build Status](https://travis-ci.org/P-H-C/phc-winner-argon2.svg?branch=master)](https://travis-ci.org/P-H-C/phc-winner-argon2) -[![Build status](https://ci.appveyor.com/api/projects/status/8nfwuwq55sgfkele?svg=true)](https://ci.appveyor.com/project/P-H-C/phc-winner-argon2) -[![codecov.io](https://codecov.io/github/P-H-C/phc-winner-argon2/coverage.svg?branch=master)](https://codecov.io/github/P-H-C/phc-winner-argon2?branch=master) - -This is the reference C implementation of Argon2, the password-hashing -function that won the [Password Hashing Competition -(PHC)](https://password-hashing.net). - -Argon2 is a password-hashing function that summarizes the state of the -art in the design of memory-hard functions and can be used to hash -passwords for credential storage, key derivation, or other applications. - -It has a simple design aimed at the highest memory filling rate and -effective use of multiple computing units, while still providing defense -against tradeoff attacks (by exploiting the cache and memory organization -of the recent processors). - -Argon2 has three variants: Argon2i, Argon2d, and Argon2id. Argon2d is faster -and uses data-depending memory access, which makes it highly resistant -against GPU cracking attacks and suitable for applications with no threats -from side-channel timing attacks (eg. cryptocurrencies). Argon2i instead -uses data-independent memory access, which is preferred for password -hashing and password-based key derivation, but it is slower as it makes -more passes over the memory to protect from tradeoff attacks. Argon2id is a -hybrid of Argon2i and Argon2d, using a combination of data-depending and -data-independent memory accesses, which gives some of Argon2i's resistance to -side-channel cache timing attacks and much of Argon2d's resistance to GPU -cracking attacks. - -Argon2i, Argon2d, and Argon2id are parametrized by: - -* A **time** cost, which defines the amount of computation realized and - therefore the execution time, given in number of iterations -* A **memory** cost, which defines the memory usage, given in kibibytes -* A **parallelism** degree, which defines the number of parallel threads - -The [Argon2 document](argon2-specs.pdf) gives detailed specs and design -rationale. - -Please report bugs as issues on this repository. - -## Usage - -`make` builds the executable `argon2`, the static library `libargon2.a`, -and the shared library `libargon2.so` (or on macOS, the dynamic library -`libargon2.dylib` -- make sure to specify the installation prefix when -you compile: `make PREFIX=/usr`). Make sure to run `make test` to verify -that your build produces valid results. `sudo make install PREFIX=/usr` -installs it to your system. - -### Command-line utility - -`argon2` is a command-line utility to test specific Argon2 instances -on your system. To show usage instructions, run -`./argon2 -h` as -``` -Usage: ./argon2 [-h] salt [-i|-d|-id] [-t iterations] [-m memory] [-p parallelism] [-l hash length] [-e|-r] [-v (10|13)] - Password is read from stdin -Parameters: - salt The salt to use, at least 8 characters - -i Use Argon2i (this is the default) - -d Use Argon2d instead of Argon2i - -id Use Argon2id instead of Argon2i - -t N Sets the number of iterations to N (default = 3) - -m N Sets the memory usage of 2^N KiB (default 12) - -p N Sets parallelism to N threads (default 1) - -l N Sets hash output length to N bytes (default 32) - -e Output only encoded hash - -r Output only the raw bytes of the hash - -v (10|13) Argon2 version (defaults to the most recent version, currently 13) - -h Print argon2 usage -``` -For example, to hash "password" using "somesalt" as a salt and doing 2 -iterations, consuming 64 MiB, using four parallel threads and an output hash -of 24 bytes -``` -$ echo -n "password" | ./argon2 somesalt -t 2 -m 16 -p 4 -l 24 -Type: Argon2i -Iterations: 2 -Memory: 65536 KiB -Parallelism: 4 -Hash: 45d7ac72e76f242b20b77b9bf9bf9d5915894e669a24e6c6 -Encoded: $argon2i$v=19$m=65536,t=2,p=4$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTmaaJObG -0.188 seconds -Verification ok -``` - -### Library - -`libargon2` provides an API to both low-level and high-level functions -for using Argon2. - -The example program below hashes the string "password" with Argon2i -using the high-level API and then using the low-level API. While the -high-level API takes the three cost parameters (time, memory, and -parallelism), the password input buffer, the salt input buffer, and the -output buffers, the low-level API takes in these and additional parameters -, as defined in [`include/argon2.h`](include/argon2.h). - -There are many additional parameters, but we will highlight three of them here. - -1. The `secret` parameter, which is used for [keyed hashing]( - https://en.wikipedia.org/wiki/Hash-based_message_authentication_code). - This allows a secret key to be input at hashing time (from some external - location) and be folded into the value of the hash. This means that even if - your salts and hashes are compromised, an attacker cannot brute-force to find - the password without the key. - -2. The `ad` parameter, which is used to fold any additional data into the hash - value. Functionally, this behaves almost exactly like the `secret` or `salt` - parameters; the `ad` parameter is folding into the value of the hash. - However, this parameter is used for different data. The `salt` should be a - random string stored alongside your password. The `secret` should be a random - key only usable at hashing time. The `ad` is for any other data. - -3. The `flags` parameter, which determines which memory should be securely - erased. This is useful if you want to securely delete the `pwd` or `secret` - fields right after they are used. To do this set `flags` to either - `ARGON2_FLAG_CLEAR_PASSWORD` or `ARGON2_FLAG_CLEAR_SECRET`. To change how - internal memory is cleared, change the global flag - `FLAG_clear_internal_memory` (defaults to clearing internal memory). - -Here the time cost `t_cost` is set to 2 iterations, the -memory cost `m_cost` is set to 216 kibibytes (64 mebibytes), -and parallelism is set to 1 (single-thread). - -Compile for example as `gcc test.c libargon2.a -Isrc -o test`, if the program -below is named `test.c` and placed in the project's root directory. - -```c -#include "argon2.h" -#include -#include -#include - -#define HASHLEN 32 -#define SALTLEN 16 -#define PWD "password" - -int main(void) -{ - uint8_t hash1[HASHLEN]; - uint8_t hash2[HASHLEN]; - - uint8_t salt[SALTLEN]; - memset( salt, 0x00, SALTLEN ); - - uint8_t *pwd = (uint8_t *)strdup(PWD); - uint32_t pwdlen = strlen((char *)pwd); - - uint32_t t_cost = 2; // 2-pass computation - uint32_t m_cost = (1<<16); // 64 mebibytes memory usage - uint32_t parallelism = 1; // number of threads and lanes - - // high-level API - argon2i_hash_raw(t_cost, m_cost, parallelism, pwd, pwdlen, salt, SALTLEN, hash1, HASHLEN); - - // low-level API - argon2_context context = { - hash2, /* output array, at least HASHLEN in size */ - HASHLEN, /* digest length */ - pwd, /* password array */ - pwdlen, /* password length */ - salt, /* salt array */ - SALTLEN, /* salt length */ - NULL, 0, /* optional secret data */ - NULL, 0, /* optional associated data */ - t_cost, m_cost, parallelism, parallelism, - ARGON2_VERSION_13, /* algorithm version */ - NULL, NULL, /* custom memory allocation / deallocation functions */ - /* by default only internal memory is cleared (pwd is not wiped) */ - ARGON2_DEFAULT_FLAGS - }; - - int rc = argon2i_ctx( &context ); - if(ARGON2_OK != rc) { - printf("Error: %s\n", argon2_error_message(rc)); - exit(1); - } - free(pwd); - - for( int i=0; i $tempfile - } else { - vs2015\build\Argon2OptGenKAT.exe $type $version > $tempfile - } - - if (19 -eq $version) { - $kats = "kats\argon2" + $type - } else { - $kats = "kats\argon2" + $type + "_v" + $version - } - - Write-Host -NoNewline "Argon2$type v=$version : " - CompareFiles $tempfile $kats $i - Write-Output "" - } - } - } - - if (Test-Path $tempfile) { - Remove-Item $tempfile - } -} - -main diff --git a/Blastproof/keygen/argon2/kats/test.sh b/Blastproof/keygen/argon2/kats/test.sh deleted file mode 100755 index b320975..0000000 --- a/Blastproof/keygen/argon2/kats/test.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -for opttest in "" "OPTTEST=1" -do - if [ "" = "$opttest" ] - then - printf "Default build\n" - else - printf "Force OPTTEST=1\n" - fi - - make genkat $opttest > /dev/null - if [ $? -ne 0 ] - then - exit $? - fi - - i=0 - for version in 16 19 - do - for type in i d id - do - i=$(($i+1)) - - printf "argon2$type v=$version: " - - if [ 19 -eq $version ] - then - kats="kats/argon2"$type - else - kats="kats/argon2"$type"_v"$version - fi - - ./genkat $type $version > tmp - if diff tmp $kats - then - printf "OK" - else - printf "ERROR" - exit $i - fi - printf "\n" - done - done -done - -rm -f tmp - -exit 0 diff --git a/Blastproof/keygen/argon2/libargon2.pc b/Blastproof/keygen/argon2/libargon2.pc deleted file mode 100644 index db37095..0000000 --- a/Blastproof/keygen/argon2/libargon2.pc +++ /dev/null @@ -1,13 +0,0 @@ -# libargon2 info for pkg-config - -prefix=/usr -exec_prefix=${prefix} -libdir=${prefix}/lib/x86_64-linux-gnu -includedir=${prefix}/include - -Name: libargon2 -Description: Development libraries for libargon2 -Version: ZERO -Libs: -L${libdir} -largon2 -lrt -ldl -Cflags: -I${includedir} -URL: https://github.com/P-H-C/phc-winner-argon2 diff --git a/Blastproof/keygen/argon2/libargon2.pc.in b/Blastproof/keygen/argon2/libargon2.pc.in deleted file mode 100644 index a0d2929..0000000 --- a/Blastproof/keygen/argon2/libargon2.pc.in +++ /dev/null @@ -1,18 +0,0 @@ -# libargon2 info for pkg-config -## Template for downstream installers: -## - replace @UPSTREAM_VER@ with current version, e.g. '20160406' -## - replace @HOST_MULTIARCH@ with target arch lib, e.g. 'lib', 'lib/x86_64-linux-gnu' or 'lib64' -## - replace @PREFIX@ with install path, e.g. '/usr', '/usr/local', '/usr/pkg' -## - replace @INCLUDE@ with include path, e.g. 'include' or 'include/argon2' - -prefix=@PREFIX@ -exec_prefix=${prefix} -libdir=${prefix}/@HOST_MULTIARCH@ -includedir=${prefix}/@INCLUDE@ - -Name: libargon2 -Description: Development libraries for libargon2 -Version: @UPSTREAM_VER@ -Libs: -L${libdir} -largon2 @EXTRA_LIBS@ -Cflags: -I${includedir} -URL: https://github.com/P-H-C/phc-winner-argon2 diff --git a/Blastproof/keygen/argon2/libargon2.so.1 b/Blastproof/keygen/argon2/libargon2.so.1 deleted file mode 100755 index 61eef91..0000000 Binary files a/Blastproof/keygen/argon2/libargon2.so.1 and /dev/null differ diff --git a/Blastproof/keygen/argon2/man/argon2.1 b/Blastproof/keygen/argon2/man/argon2.1 deleted file mode 100644 index 77c0f07..0000000 --- a/Blastproof/keygen/argon2/man/argon2.1 +++ /dev/null @@ -1,57 +0,0 @@ -.TH ARGON2 "1" "April 2016" "argon2 " "User Commands" - -.SH NAME -argon2 \- generate argon2 hashes - -.SH SYNOPSIS -.B argon2 salt -.RB [ OPTIONS ] - -.SH DESCRIPTION -Generate Argon2 hashes from the command line. - -The supplied salt (the first argument to the command) must be at least -8 octets in length, and the password is supplied on standard input. - -By default, this uses Argon2i variant (where memory access is -independent of secret data) which is the preferred one for password -hashing and password-based key derivation. - -.SH OPTIONS -.TP -.B \-h -Display tool usage -.TP -.B \-d -Use Argon2d instead of Argon2i (Argon2i is the default) -.TP -.B \-id -Use Argon2id instead of Argon2i (Argon2i is the default) -.TP -.BI \-t " N" -Sets the number of iterations to N (default = 3) -.TP -.BI \-m " N" -Sets the memory usage of 2^N KiB (default = 12) -.TP -.BI \-p " N" -Sets parallelism to N threads (default = 1) -.TP -.BI \-l " N" -Sets hash output length to N bytes (default = 32) -.TP -.B \-e -Output only encoded hash -.TP -.B \-r -Output only the raw bytes of the hash -.TP -.B \-v (10|13) -Argon2 version (defaults to the most recent version, currently 13) - -.SH COPYRIGHT -This manpage was written by \fBDaniel Kahn Gillmor\fR for the Debian -distribution (but may be used by others). It is released, like the -rest of this Argon2 implementation, under a dual license. You may use this work -under the terms of a Creative Commons CC0 1.0 License/Waiver or the Apache -Public License 2.0, at your option. diff --git a/Blastproof/keygen/argon2/src/argon2.o b/Blastproof/keygen/argon2/src/argon2.o deleted file mode 100644 index ea9d0ad..0000000 Binary files a/Blastproof/keygen/argon2/src/argon2.o and /dev/null differ diff --git a/Blastproof/keygen/argon2/src/bench.c b/Blastproof/keygen/argon2/src/bench.c deleted file mode 100644 index 6335519..0000000 --- a/Blastproof/keygen/argon2/src/bench.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#include -#include -#include -#include -#include -#ifdef _WIN32 -#include -#endif - -#include "argon2.h" - -static uint64_t rdtsc(void) { -#ifdef _WIN32 - return __rdtsc(); -#else -#if defined(__amd64__) || defined(__x86_64__) - uint64_t rax, rdx; - __asm__ __volatile__("rdtsc" : "=a"(rax), "=d"(rdx) : :); - return (rdx << 32) | rax; -#elif defined(__i386__) || defined(__i386) || defined(__X86__) - uint64_t rax; - __asm__ __volatile__("rdtsc" : "=A"(rax) : :); - return rax; -#else -#error "Not implemented!" -#endif -#endif -} - -/* - * Benchmarks Argon2 with salt length 16, password length 16, t_cost 3, - and different m_cost and threads - */ -static void benchmark() { -#define BENCH_OUTLEN 16 -#define BENCH_INLEN 16 - const uint32_t inlen = BENCH_INLEN; - const unsigned outlen = BENCH_OUTLEN; - unsigned char out[BENCH_OUTLEN]; - unsigned char pwd_array[BENCH_INLEN]; - unsigned char salt_array[BENCH_INLEN]; -#undef BENCH_INLEN -#undef BENCH_OUTLEN - - uint32_t t_cost = 3; - uint32_t m_cost; - uint32_t thread_test[4] = {1, 2, 4, 8}; - argon2_type types[3] = {Argon2_i, Argon2_d, Argon2_id}; - - memset(pwd_array, 0, inlen); - memset(salt_array, 1, inlen); - - for (m_cost = (uint32_t)1 << 10; m_cost <= (uint32_t)1 << 22; m_cost *= 2) { - unsigned i; - for (i = 0; i < 4; ++i) { - double run_time = 0; - uint32_t thread_n = thread_test[i]; - - unsigned j; - for (j = 0; j < 3; ++j) { - clock_t start_time, stop_time; - uint64_t start_cycles, stop_cycles; - uint64_t delta; - double mcycles; - - argon2_type type = types[j]; - start_time = clock(); - start_cycles = rdtsc(); - - argon2_hash(t_cost, m_cost, thread_n, pwd_array, inlen, - salt_array, inlen, out, outlen, NULL, 0, type, - ARGON2_VERSION_NUMBER); - - stop_cycles = rdtsc(); - stop_time = clock(); - - delta = (stop_cycles - start_cycles) / (m_cost); - mcycles = (double)(stop_cycles - start_cycles) / (1UL << 20); - run_time += ((double)stop_time - start_time) / (CLOCKS_PER_SEC); - - printf("%s %d iterations %d MiB %d threads: %2.2f cpb %2.2f " - "Mcycles \n", argon2_type2string(type, 1), t_cost, - m_cost >> 10, thread_n, (float)delta / 1024, mcycles); - } - - printf("%2.4f seconds\n\n", run_time); - } - } -} - -int main() { - benchmark(); - return ARGON2_OK; -} diff --git a/Blastproof/keygen/argon2/src/blake2/blake2b.o b/Blastproof/keygen/argon2/src/blake2/blake2b.o deleted file mode 100644 index 6bbb15a..0000000 Binary files a/Blastproof/keygen/argon2/src/blake2/blake2b.o and /dev/null differ diff --git a/Blastproof/keygen/argon2/src/core.o b/Blastproof/keygen/argon2/src/core.o deleted file mode 100644 index 9b9904c..0000000 Binary files a/Blastproof/keygen/argon2/src/core.o and /dev/null differ diff --git a/Blastproof/keygen/argon2/src/encoding.o b/Blastproof/keygen/argon2/src/encoding.o deleted file mode 100644 index 541a732..0000000 Binary files a/Blastproof/keygen/argon2/src/encoding.o and /dev/null differ diff --git a/Blastproof/keygen/argon2/src/genkat.c b/Blastproof/keygen/argon2/src/genkat.c deleted file mode 100644 index dbbc072..0000000 --- a/Blastproof/keygen/argon2/src/genkat.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#include -#include -#include -#include "argon2.h" -#include "core.h" -#ifdef __MINGW32__ -#include -#else -/* Don't use (it's not C89) */ -#define PRIx64 "llx" -#endif - -void initial_kat(const uint8_t *blockhash, const argon2_context *context, - argon2_type type) { - unsigned i; - - if (blockhash != NULL && context != NULL) { - printf("=======================================\n"); - - printf("%s version number %d\n", argon2_type2string(type, 1), - context->version); - - printf("=======================================\n"); - - - printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag " - "length: %u bytes\n", - context->m_cost, context->t_cost, context->lanes, - context->outlen); - - printf("Password[%u]: ", context->pwdlen); - - if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { - printf("CLEARED\n"); - } else { - for (i = 0; i < context->pwdlen; ++i) { - printf("%2.2x ", ((unsigned char *)context->pwd)[i]); - } - - printf("\n"); - } - - printf("Salt[%u]: ", context->saltlen); - - for (i = 0; i < context->saltlen; ++i) { - printf("%2.2x ", ((unsigned char *)context->salt)[i]); - } - - printf("\n"); - - printf("Secret[%u]: ", context->secretlen); - - if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { - printf("CLEARED\n"); - } else { - for (i = 0; i < context->secretlen; ++i) { - printf("%2.2x ", ((unsigned char *)context->secret)[i]); - } - - printf("\n"); - } - - printf("Associated data[%u]: ", context->adlen); - - for (i = 0; i < context->adlen; ++i) { - printf("%2.2x ", ((unsigned char *)context->ad)[i]); - } - - printf("\n"); - - printf("Pre-hashing digest: "); - - for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) { - printf("%2.2x ", ((unsigned char *)blockhash)[i]); - } - - printf("\n"); - } -} - -void print_tag(const void *out, uint32_t outlen) { - unsigned i; - if (out != NULL) { - printf("Tag: "); - - for (i = 0; i < outlen; ++i) { - printf("%2.2x ", ((uint8_t *)out)[i]); - } - - printf("\n"); - } -} - -void internal_kat(const argon2_instance_t *instance, uint32_t pass) { - - if (instance != NULL) { - uint32_t i, j; - printf("\n After pass %u:\n", pass); - - for (i = 0; i < instance->memory_blocks; ++i) { - uint32_t how_many_words = - (instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK) - ? 1 - : ARGON2_QWORDS_IN_BLOCK; - - for (j = 0; j < how_many_words; ++j) - printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j, - (unsigned long long)instance->memory[i].v[j]); - } - } -} - -static void fatal(const char *error) { - fprintf(stderr, "Error: %s\n", error); - exit(1); -} - -static void generate_testvectors(argon2_type type, const uint32_t version) { -#define TEST_OUTLEN 32 -#define TEST_PWDLEN 32 -#define TEST_SALTLEN 16 -#define TEST_SECRETLEN 8 -#define TEST_ADLEN 12 - argon2_context context; - - unsigned char out[TEST_OUTLEN]; - unsigned char pwd[TEST_PWDLEN]; - unsigned char salt[TEST_SALTLEN]; - unsigned char secret[TEST_SECRETLEN]; - unsigned char ad[TEST_ADLEN]; - const allocate_fptr myown_allocator = NULL; - const deallocate_fptr myown_deallocator = NULL; - - unsigned t_cost = 3; - unsigned m_cost = 32; - unsigned lanes = 4; - - memset(pwd, 1, TEST_OUTLEN); - memset(salt, 2, TEST_SALTLEN); - memset(secret, 3, TEST_SECRETLEN); - memset(ad, 4, TEST_ADLEN); - - context.out = out; - context.outlen = TEST_OUTLEN; - context.version = version; - context.pwd = pwd; - context.pwdlen = TEST_PWDLEN; - context.salt = salt; - context.saltlen = TEST_SALTLEN; - context.secret = secret; - context.secretlen = TEST_SECRETLEN; - context.ad = ad; - context.adlen = TEST_ADLEN; - context.t_cost = t_cost; - context.m_cost = m_cost; - context.lanes = lanes; - context.threads = lanes; - context.allocate_cbk = myown_allocator; - context.free_cbk = myown_deallocator; - context.flags = ARGON2_DEFAULT_FLAGS; - -#undef TEST_OUTLEN -#undef TEST_PWDLEN -#undef TEST_SALTLEN -#undef TEST_SECRETLEN -#undef TEST_ADLEN - - argon2_ctx(&context, type); -} - -int main(int argc, char *argv[]) { - /* Get and check Argon2 type */ - const char *type_str = (argc > 1) ? argv[1] : "i"; - argon2_type type = Argon2_i; - uint32_t version = ARGON2_VERSION_NUMBER; - if (!strcmp(type_str, "d")) { - type = Argon2_d; - } else if (!strcmp(type_str, "i")) { - type = Argon2_i; - } else if (!strcmp(type_str, "id")) { - type = Argon2_id; - } else { - fatal("wrong Argon2 type"); - } - - /* Get and check Argon2 version number */ - if (argc > 2) { - version = strtoul(argv[2], NULL, 10); - } - if (ARGON2_VERSION_10 != version && ARGON2_VERSION_NUMBER != version) { - fatal("wrong Argon2 version number"); - } - - generate_testvectors(type, version); - return ARGON2_OK; -} diff --git a/Blastproof/keygen/argon2/src/genkat.h b/Blastproof/keygen/argon2/src/genkat.h deleted file mode 100644 index 3a7162a..0000000 --- a/Blastproof/keygen/argon2/src/genkat.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef ARGON2_KAT_H -#define ARGON2_KAT_H - -#include "core.h" - -/* - * Initial KAT function that prints the inputs to the file - * @param blockhash Array that contains pre-hashing digest - * @param context Holds inputs - * @param type Argon2 type - * @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes - * @pre context member pointers must point to allocated memory of size according - * to the length values - */ -void initial_kat(const uint8_t *blockhash, const argon2_context *context, - argon2_type type); - -/* - * Function that prints the output tag - * @param out output array pointer - * @param outlen digest length - * @pre out must point to @a outlen bytes - **/ -void print_tag(const void *out, uint32_t outlen); - -/* - * Function that prints the internal state at given moment - * @param instance pointer to the current instance - * @param pass current pass number - * @pre instance must have necessary memory allocated - **/ -void internal_kat(const argon2_instance_t *instance, uint32_t pass); - -#endif diff --git a/Blastproof/keygen/argon2/src/opt.o b/Blastproof/keygen/argon2/src/opt.o deleted file mode 100644 index 95b6e0d..0000000 Binary files a/Blastproof/keygen/argon2/src/opt.o and /dev/null differ diff --git a/Blastproof/keygen/argon2/src/ref.c b/Blastproof/keygen/argon2/src/ref.c deleted file mode 100644 index 10e45eb..0000000 --- a/Blastproof/keygen/argon2/src/ref.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#include -#include -#include - -#include "argon2.h" -#include "core.h" - -#include "blake2/blamka-round-ref.h" -#include "blake2/blake2-impl.h" -#include "blake2/blake2.h" - - -/* - * Function fills a new memory block and optionally XORs the old block over the new one. - * @next_block must be initialized. - * @param prev_block Pointer to the previous block - * @param ref_block Pointer to the reference block - * @param next_block Pointer to the block to be constructed - * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) - * @pre all block pointers must be valid - */ -static void fill_block(const block *prev_block, const block *ref_block, - block *next_block, int with_xor) { - block blockR, block_tmp; - unsigned i; - - copy_block(&blockR, ref_block); - xor_block(&blockR, prev_block); - copy_block(&block_tmp, &blockR); - /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */ - if (with_xor) { - /* Saving the next block contents for XOR over: */ - xor_block(&block_tmp, next_block); - /* Now blockR = ref_block + prev_block and - block_tmp = ref_block + prev_block + next_block */ - } - - /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then - (16,17,..31)... finally (112,113,...127) */ - for (i = 0; i < 8; ++i) { - BLAKE2_ROUND_NOMSG( - blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], - blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], - blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], - blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], - blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], - blockR.v[16 * i + 15]); - } - - /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then - (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ - for (i = 0; i < 8; i++) { - BLAKE2_ROUND_NOMSG( - blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], - blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], - blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], - blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], - blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], - blockR.v[2 * i + 113]); - } - - copy_block(next_block, &block_tmp); - xor_block(next_block, &blockR); -} - -static void next_addresses(block *address_block, block *input_block, - const block *zero_block) { - input_block->v[6]++; - fill_block(zero_block, input_block, address_block, 0); - fill_block(zero_block, address_block, address_block, 0); -} - -void fill_segment(const argon2_instance_t *instance, - argon2_position_t position) { - block *ref_block = NULL, *curr_block = NULL; - block address_block, input_block, zero_block; - uint64_t pseudo_rand, ref_index, ref_lane; - uint32_t prev_offset, curr_offset; - uint32_t starting_index; - uint32_t i; - int data_independent_addressing; - - if (instance == NULL) { - return; - } - - data_independent_addressing = - (instance->type == Argon2_i) || - (instance->type == Argon2_id && (position.pass == 0) && - (position.slice < ARGON2_SYNC_POINTS / 2)); - - if (data_independent_addressing) { - init_block_value(&zero_block, 0); - init_block_value(&input_block, 0); - - input_block.v[0] = position.pass; - input_block.v[1] = position.lane; - input_block.v[2] = position.slice; - input_block.v[3] = instance->memory_blocks; - input_block.v[4] = instance->passes; - input_block.v[5] = instance->type; - } - - starting_index = 0; - - if ((0 == position.pass) && (0 == position.slice)) { - starting_index = 2; /* we have already generated the first two blocks */ - - /* Don't forget to generate the first block of addresses: */ - if (data_independent_addressing) { - next_addresses(&address_block, &input_block, &zero_block); - } - } - - /* Offset of the current block */ - curr_offset = position.lane * instance->lane_length + - position.slice * instance->segment_length + starting_index; - - if (0 == curr_offset % instance->lane_length) { - /* Last block in this lane */ - prev_offset = curr_offset + instance->lane_length - 1; - } else { - /* Previous block */ - prev_offset = curr_offset - 1; - } - - for (i = starting_index; i < instance->segment_length; - ++i, ++curr_offset, ++prev_offset) { - /*1.1 Rotating prev_offset if needed */ - if (curr_offset % instance->lane_length == 1) { - prev_offset = curr_offset - 1; - } - - /* 1.2 Computing the index of the reference block */ - /* 1.2.1 Taking pseudo-random value from the previous block */ - if (data_independent_addressing) { - if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { - next_addresses(&address_block, &input_block, &zero_block); - } - pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; - } else { - pseudo_rand = instance->memory[prev_offset].v[0]; - } - - /* 1.2.2 Computing the lane of the reference block */ - ref_lane = ((pseudo_rand >> 32)) % instance->lanes; - - if ((position.pass == 0) && (position.slice == 0)) { - /* Can not reference other lanes yet */ - ref_lane = position.lane; - } - - /* 1.2.3 Computing the number of possible reference block within the - * lane. - */ - position.index = i; - ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, - ref_lane == position.lane); - - /* 2 Creating a new block */ - ref_block = - instance->memory + instance->lane_length * ref_lane + ref_index; - curr_block = instance->memory + curr_offset; - if (ARGON2_VERSION_10 == instance->version) { - /* version 1.2.1 and earlier: overwrite, not XOR */ - fill_block(instance->memory + prev_offset, ref_block, curr_block, 0); - } else { - if(0 == position.pass) { - fill_block(instance->memory + prev_offset, ref_block, - curr_block, 0); - } else { - fill_block(instance->memory + prev_offset, ref_block, - curr_block, 1); - } - } - } -} diff --git a/Blastproof/keygen/argon2/src/run.c b/Blastproof/keygen/argon2/src/run.c deleted file mode 100644 index 702b618..0000000 --- a/Blastproof/keygen/argon2/src/run.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#define _GNU_SOURCE 1 - -#include -#include -#include -#include -#include - -#include "argon2.h" -#include "core.h" - -#define T_COST_DEF 3 -#define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */ -#define LANES_DEF 1 -#define THREADS_DEF 1 -#define OUTLEN_DEF 32 -#define MAX_PASS_LEN 128 - -#define UNUSED_PARAMETER(x) (void)(x) - -static void usage(const char *cmd) { - printf("Usage: %s [-h] salt [-i|-d|-id] [-t iterations] " - "[-m log2(memory in KiB) | -k memory in KiB] [-p parallelism] " - "[-l hash length] [-e|-r] [-v (10|13)]\n", - cmd); - printf("\tPassword is read from stdin\n"); - printf("Parameters:\n"); - printf("\tsalt\t\tThe salt to use, at least 8 characters\n"); - printf("\t-i\t\tUse Argon2i (this is the default)\n"); - printf("\t-d\t\tUse Argon2d instead of Argon2i\n"); - printf("\t-id\t\tUse Argon2id instead of Argon2i\n"); - printf("\t-t N\t\tSets the number of iterations to N (default = %d)\n", - T_COST_DEF); - printf("\t-m N\t\tSets the memory usage of 2^N KiB (default %d)\n", - LOG_M_COST_DEF); - printf("\t-k N\t\tSets the memory usage of N KiB (default %d)\n", - 1 << LOG_M_COST_DEF); - printf("\t-p N\t\tSets parallelism to N threads (default %d)\n", - THREADS_DEF); - printf("\t-l N\t\tSets hash output length to N bytes (default %d)\n", - OUTLEN_DEF); - printf("\t-e\t\tOutput only encoded hash\n"); - printf("\t-r\t\tOutput only the raw bytes of the hash\n"); - printf("\t-v (10|13)\tArgon2 version (defaults to the most recent version, currently %x)\n", - ARGON2_VERSION_NUMBER); - printf("\t-h\t\tPrint %s usage\n", cmd); -} - -static void fatal(const char *error) { - fprintf(stderr, "Error: %s\n", error); - exit(1); -} - -static void print_hex(uint8_t *bytes, size_t bytes_len) { - size_t i; - for (i = 0; i < bytes_len; ++i) { - printf("%02x", bytes[i]); - } - printf("\n"); -} - -/* -Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the -Base64-encoded hash string -@out output array with at least 32 bytes allocated -@pwd NULL-terminated string, presumably from argv[] -@salt salt array -@t_cost number of iterations -@m_cost amount of requested memory in KB -@lanes amount of requested parallelism -@threads actual parallelism -@type Argon2 type we want to run -@encoded_only display only the encoded hash -@raw_only display only the hexadecimal of the hash -@version Argon2 version -*/ -static void run(uint32_t outlen, char *pwd, size_t pwdlen, char *salt, uint32_t t_cost, - uint32_t m_cost, uint32_t lanes, uint32_t threads, - argon2_type type, int encoded_only, int raw_only, uint32_t version) { - clock_t start_time, stop_time; - size_t saltlen, encodedlen; - int result; - unsigned char * out = NULL; - char * encoded = NULL; - - start_time = clock(); - - if (!pwd) { - fatal("password missing"); - } - - if (!salt) { - clear_internal_memory(pwd, pwdlen); - fatal("salt missing"); - } - - saltlen = strlen(salt); - if(UINT32_MAX < saltlen) { - fatal("salt is too long"); - } - - UNUSED_PARAMETER(lanes); - - out = malloc(outlen + 1); - if (!out) { - clear_internal_memory(pwd, pwdlen); - fatal("could not allocate memory for output"); - } - - encodedlen = argon2_encodedlen(t_cost, m_cost, lanes, (uint32_t)saltlen, outlen, type); - encoded = malloc(encodedlen + 1); - if (!encoded) { - clear_internal_memory(pwd, pwdlen); - fatal("could not allocate memory for hash"); - } - - result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen, - out, outlen, encoded, encodedlen, type, - version); - if (result != ARGON2_OK) - fatal(argon2_error_message(result)); - - stop_time = clock(); - - if (encoded_only) - puts(encoded); - - if (raw_only) - print_hex(out, outlen); - - if (encoded_only || raw_only) { - free(out); - free(encoded); - return; - } - - printf("Hash:\t\t"); - print_hex(out, outlen); - free(out); - - printf("Encoded:\t%s\n", encoded); - - printf("%2.3f seconds\n", - ((double)stop_time - start_time) / (CLOCKS_PER_SEC)); - - result = argon2_verify(encoded, pwd, pwdlen, type); - if (result != ARGON2_OK) - fatal(argon2_error_message(result)); - printf("Verification ok\n"); - free(encoded); -} - -int main(int argc, char *argv[]) { - uint32_t outlen = OUTLEN_DEF; - uint32_t m_cost = 1 << LOG_M_COST_DEF; - uint32_t t_cost = T_COST_DEF; - uint32_t lanes = LANES_DEF; - uint32_t threads = THREADS_DEF; - argon2_type type = Argon2_i; /* Argon2i is the default type */ - int types_specified = 0; - int m_cost_specified = 0; - int encoded_only = 0; - int raw_only = 0; - uint32_t version = ARGON2_VERSION_NUMBER; - int i; - size_t pwdlen; - char pwd[MAX_PASS_LEN], *salt; - - if (argc < 2) { - usage(argv[0]); - return ARGON2_MISSING_ARGS; - } else if (argc >= 2 && strcmp(argv[1], "-h") == 0) { - usage(argv[0]); - return 1; - } - - /* get password from stdin */ - pwdlen = fread(pwd, 1, sizeof pwd, stdin); - if(pwdlen < 1) { - fatal("no password read"); - } - if(pwdlen == MAX_PASS_LEN) { - fatal("Provided password longer than supported in command line utility"); - } - - salt = argv[1]; - - /* parse options */ - for (i = 2; i < argc; i++) { - const char *a = argv[i]; - unsigned long input = 0; - if (!strcmp(a, "-h")) { - usage(argv[0]); - return 1; - } else if (!strcmp(a, "-m")) { - if (m_cost_specified) { - fatal("-m or -k can only be used once"); - } - m_cost_specified = 1; - if (i < argc - 1) { - i++; - input = strtoul(argv[i], NULL, 10); - if (input == 0 || input == ULONG_MAX || - input > ARGON2_MAX_MEMORY_BITS) { - fatal("bad numeric input for -m"); - } - m_cost = ARGON2_MIN(UINT64_C(1) << input, UINT32_C(0xFFFFFFFF)); - if (m_cost > ARGON2_MAX_MEMORY) { - fatal("m_cost overflow"); - } - continue; - } else { - fatal("missing -m argument"); - } - } else if (!strcmp(a, "-k")) { - if (m_cost_specified) { - fatal("-m or -k can only be used once"); - } - m_cost_specified = 1; - if (i < argc - 1) { - i++; - input = strtoul(argv[i], NULL, 10); - if (input == 0 || input == ULONG_MAX) { - fatal("bad numeric input for -k"); - } - m_cost = ARGON2_MIN(input, UINT32_C(0xFFFFFFFF)); - if (m_cost > ARGON2_MAX_MEMORY) { - fatal("m_cost overflow"); - } - continue; - } else { - fatal("missing -k argument"); - } - } else if (!strcmp(a, "-t")) { - if (i < argc - 1) { - i++; - input = strtoul(argv[i], NULL, 10); - if (input == 0 || input == ULONG_MAX || - input > ARGON2_MAX_TIME) { - fatal("bad numeric input for -t"); - } - t_cost = input; - continue; - } else { - fatal("missing -t argument"); - } - } else if (!strcmp(a, "-p")) { - if (i < argc - 1) { - i++; - input = strtoul(argv[i], NULL, 10); - if (input == 0 || input == ULONG_MAX || - input > ARGON2_MAX_THREADS || input > ARGON2_MAX_LANES) { - fatal("bad numeric input for -p"); - } - threads = input; - lanes = threads; - continue; - } else { - fatal("missing -p argument"); - } - } else if (!strcmp(a, "-l")) { - if (i < argc - 1) { - i++; - input = strtoul(argv[i], NULL, 10); - outlen = input; - continue; - } else { - fatal("missing -l argument"); - } - } else if (!strcmp(a, "-i")) { - type = Argon2_i; - ++types_specified; - } else if (!strcmp(a, "-d")) { - type = Argon2_d; - ++types_specified; - } else if (!strcmp(a, "-id")) { - type = Argon2_id; - ++types_specified; - } else if (!strcmp(a, "-e")) { - encoded_only = 1; - } else if (!strcmp(a, "-r")) { - raw_only = 1; - } else if (!strcmp(a, "-v")) { - if (i < argc - 1) { - i++; - if (!strcmp(argv[i], "10")) { - version = ARGON2_VERSION_10; - } else if (!strcmp(argv[i], "13")) { - version = ARGON2_VERSION_13; - } else { - fatal("invalid Argon2 version"); - } - } else { - fatal("missing -v argument"); - } - } else { - fatal("unknown argument"); - } - } - - if (types_specified > 1) { - fatal("cannot specify multiple Argon2 types"); - } - - if(encoded_only && raw_only) - fatal("cannot provide both -e and -r"); - - if(!encoded_only && !raw_only) { - printf("Type:\t\t%s\n", argon2_type2string(type, 1)); - printf("Iterations:\t%u\n", t_cost); - printf("Memory:\t\t%u KiB\n", m_cost); - printf("Parallelism:\t%u\n", lanes); - } - - run(outlen, pwd, pwdlen, salt, t_cost, m_cost, lanes, threads, type, - encoded_only, raw_only, version); - - return ARGON2_OK; -} - diff --git a/Blastproof/keygen/argon2/src/test.c b/Blastproof/keygen/argon2/src/test.c deleted file mode 100644 index 055c19a..0000000 --- a/Blastproof/keygen/argon2/src/test.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#include -#include -#include -#include -#include -#include - -#include "argon2.h" - -#define OUT_LEN 32 -#define ENCODED_LEN 108 - -/* Test harness will assert: - * argon2_hash() returns ARGON2_OK - * HEX output matches expected - * encoded output matches expected - * argon2_verify() correctly verifies value - */ - -void hashtest(uint32_t version, uint32_t t, uint32_t m, uint32_t p, char *pwd, - char *salt, char *hexref, char *mcfref, argon2_type type) { - unsigned char out[OUT_LEN]; - unsigned char hex_out[OUT_LEN * 2 + 4]; - char encoded[ENCODED_LEN]; - int ret, i; - - printf("Hash test: $v=%d t=%d, m=%d, p=%d, pass=%s, salt=%s: ", version, - t, m, p, pwd, salt); - - ret = argon2_hash(t, 1 << m, p, pwd, strlen(pwd), salt, strlen(salt), out, - OUT_LEN, encoded, ENCODED_LEN, type, version); - assert(ret == ARGON2_OK); - - for (i = 0; i < OUT_LEN; ++i) - sprintf((char *)(hex_out + i * 2), "%02x", out[i]); - assert(memcmp(hex_out, hexref, OUT_LEN * 2) == 0); - - if (ARGON2_VERSION_NUMBER == version) { - assert(memcmp(encoded, mcfref, strlen(mcfref)) == 0); - } - - ret = argon2_verify(encoded, pwd, strlen(pwd), type); - assert(ret == ARGON2_OK); - ret = argon2_verify(mcfref, pwd, strlen(pwd), type); - assert(ret == ARGON2_OK); - - printf("PASS\n"); -} - -int main() { - int ret; - unsigned char out[OUT_LEN]; - char const *msg; - int version; - - version = ARGON2_VERSION_10; - printf("Test Argon2i version number: %02x\n", version); - - /* Multiple test cases for various input values */ - hashtest(version, 2, 16, 1, "password", "somesalt", - "f6c4db4a54e2a370627aff3db6176b94a2a209a62c8e36152711802f7b30c694", - "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" - "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", Argon2_i); -#ifdef TEST_LARGE_RAM - hashtest(version, 2, 20, 1, "password", "somesalt", - "9690ec55d28d3ed32562f2e73ea62b02b018757643a2ae6e79528459de8106e9", - "$argon2i$m=1048576,t=2,p=1$c29tZXNhbHQ" - "$lpDsVdKNPtMlYvLnPqYrArAYdXZDoq5ueVKEWd6BBuk", Argon2_i); -#endif - hashtest(version, 2, 18, 1, "password", "somesalt", - "3e689aaa3d28a77cf2bc72a51ac53166761751182f1ee292e3f677a7da4c2467", - "$argon2i$m=262144,t=2,p=1$c29tZXNhbHQ" - "$Pmiaqj0op3zyvHKlGsUxZnYXURgvHuKS4/Z3p9pMJGc", Argon2_i); - hashtest(version, 2, 8, 1, "password", "somesalt", - "fd4dd83d762c49bdeaf57c47bdcd0c2f1babf863fdeb490df63ede9975fccf06", - "$argon2i$m=256,t=2,p=1$c29tZXNhbHQ" - "$/U3YPXYsSb3q9XxHvc0MLxur+GP960kN9j7emXX8zwY", Argon2_i); - hashtest(version, 2, 8, 2, "password", "somesalt", - "b6c11560a6a9d61eac706b79a2f97d68b4463aa3ad87e00c07e2b01e90c564fb", - "$argon2i$m=256,t=2,p=2$c29tZXNhbHQ" - "$tsEVYKap1h6scGt5ovl9aLRGOqOth+AMB+KwHpDFZPs", Argon2_i); - hashtest(version, 1, 16, 1, "password", "somesalt", - "81630552b8f3b1f48cdb1992c4c678643d490b2b5eb4ff6c4b3438b5621724b2", - "$argon2i$m=65536,t=1,p=1$c29tZXNhbHQ" - "$gWMFUrjzsfSM2xmSxMZ4ZD1JCytetP9sSzQ4tWIXJLI", Argon2_i); - hashtest(version, 4, 16, 1, "password", "somesalt", - "f212f01615e6eb5d74734dc3ef40ade2d51d052468d8c69440a3a1f2c1c2847b", - "$argon2i$m=65536,t=4,p=1$c29tZXNhbHQ" - "$8hLwFhXm6110c03D70Ct4tUdBSRo2MaUQKOh8sHChHs", Argon2_i); - hashtest(version, 2, 16, 1, "differentpassword", "somesalt", - "e9c902074b6754531a3a0be519e5baf404b30ce69b3f01ac3bf21229960109a3", - "$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" - "$6ckCB0tnVFMaOgvlGeW69ASzDOabPwGsO/ISKZYBCaM", Argon2_i); - hashtest(version, 2, 16, 1, "password", "diffsalt", - "79a103b90fe8aef8570cb31fc8b22259778916f8336b7bdac3892569d4f1c497", - "$argon2i$m=65536,t=2,p=1$ZGlmZnNhbHQ" - "$eaEDuQ/orvhXDLMfyLIiWXeJFvgza3vaw4kladTxxJc", Argon2_i); - - /* Error state tests */ - - /* Handle an invalid encoding correctly (it is missing a $) */ - ret = argon2_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ" - "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", strlen("password"), Argon2_i); - assert(ret == ARGON2_DECODING_FAIL); - printf("Recognise an invalid encoding: PASS\n"); - - /* Handle an invalid encoding correctly (it is missing a $) */ - ret = argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" - "9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", strlen("password"), Argon2_i); - assert(ret == ARGON2_DECODING_FAIL); - printf("Recognise an invalid encoding: PASS\n"); - - /* Handle an invalid encoding correctly (salt is too short) */ - ret = argon2_verify("$argon2i$m=65536,t=2,p=1$" - "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", strlen("password"), Argon2_i); - assert(ret == ARGON2_SALT_TOO_SHORT); - printf("Recognise an invalid salt in encoding: PASS\n"); - - /* Handle an mismatching hash (the encoded password is "passwore") */ - ret = argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" - "$b2G3seW+uPzerwQQC+/E1K50CLLO7YXy0JRcaTuswRo", - "password", strlen("password"), Argon2_i); - assert(ret == ARGON2_VERIFY_MISMATCH); - printf("Verify with mismatched password: PASS\n"); - - msg = argon2_error_message(ARGON2_DECODING_FAIL); - assert(strcmp(msg, "Decoding failed") == 0); - printf("Decode an error message: PASS\n"); - - printf("\n"); - - version = ARGON2_VERSION_NUMBER; - printf("Test Argon2i version number: %02x\n", version); - - /* Multiple test cases for various input values */ - hashtest(version, 2, 16, 1, "password", "somesalt", - "c1628832147d9720c5bd1cfd61367078729f6dfb6f8fea9ff98158e0d7816ed0", - "$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" - "$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", Argon2_i); -#ifdef TEST_LARGE_RAM - hashtest(version, 2, 20, 1, "password", "somesalt", - "d1587aca0922c3b5d6a83edab31bee3c4ebaef342ed6127a55d19b2351ad1f41", - "$argon2i$v=19$m=1048576,t=2,p=1$c29tZXNhbHQ" - "$0Vh6ygkiw7XWqD7asxvuPE667zQu1hJ6VdGbI1GtH0E", Argon2_i); -#endif - hashtest(version, 2, 18, 1, "password", "somesalt", - "296dbae80b807cdceaad44ae741b506f14db0959267b183b118f9b24229bc7cb", - "$argon2i$v=19$m=262144,t=2,p=1$c29tZXNhbHQ" - "$KW266AuAfNzqrUSudBtQbxTbCVkmexg7EY+bJCKbx8s", Argon2_i); - hashtest(version, 2, 8, 1, "password", "somesalt", - "89e9029f4637b295beb027056a7336c414fadd43f6b208645281cb214a56452f", - "$argon2i$v=19$m=256,t=2,p=1$c29tZXNhbHQ" - "$iekCn0Y3spW+sCcFanM2xBT63UP2sghkUoHLIUpWRS8", Argon2_i); - hashtest(version, 2, 8, 2, "password", "somesalt", - "4ff5ce2769a1d7f4c8a491df09d41a9fbe90e5eb02155a13e4c01e20cd4eab61", - "$argon2i$v=19$m=256,t=2,p=2$c29tZXNhbHQ" - "$T/XOJ2mh1/TIpJHfCdQan76Q5esCFVoT5MAeIM1Oq2E", Argon2_i); - hashtest(version, 1, 16, 1, "password", "somesalt", - "d168075c4d985e13ebeae560cf8b94c3b5d8a16c51916b6f4ac2da3ac11bbecf", - "$argon2i$v=19$m=65536,t=1,p=1$c29tZXNhbHQ" - "$0WgHXE2YXhPr6uVgz4uUw7XYoWxRkWtvSsLaOsEbvs8", Argon2_i); - hashtest(version, 4, 16, 1, "password", "somesalt", - "aaa953d58af3706ce3df1aefd4a64a84e31d7f54175231f1285259f88174ce5b", - "$argon2i$v=19$m=65536,t=4,p=1$c29tZXNhbHQ" - "$qqlT1YrzcGzj3xrv1KZKhOMdf1QXUjHxKFJZ+IF0zls", Argon2_i); - hashtest(version, 2, 16, 1, "differentpassword", "somesalt", - "14ae8da01afea8700c2358dcef7c5358d9021282bd88663a4562f59fb74d22ee", - "$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" - "$FK6NoBr+qHAMI1jc73xTWNkCEoK9iGY6RWL1n7dNIu4", Argon2_i); - hashtest(version, 2, 16, 1, "password", "diffsalt", - "b0357cccfbef91f3860b0dba447b2348cbefecadaf990abfe9cc40726c521271", - "$argon2i$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ" - "$sDV8zPvvkfOGCw26RHsjSMvv7K2vmQq/6cxAcmxSEnE", Argon2_i); - - - /* Error state tests */ - - /* Handle an invalid encoding correctly (it is missing a $) */ - ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1c29tZXNhbHQ" - "$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", - "password", strlen("password"), Argon2_i); - assert(ret == ARGON2_DECODING_FAIL); - printf("Recognise an invalid encoding: PASS\n"); - - /* Handle an invalid encoding correctly (it is missing a $) */ - ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" - "wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", - "password", strlen("password"), Argon2_i); - assert(ret == ARGON2_DECODING_FAIL); - printf("Recognise an invalid encoding: PASS\n"); - - /* Handle an invalid encoding correctly (salt is too short) */ - ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$" - "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", - "password", strlen("password"), Argon2_i); - assert(ret == ARGON2_SALT_TOO_SHORT); - printf("Recognise an invalid salt in encoding: PASS\n"); - - /* Handle an mismatching hash (the encoded password is "passwore") */ - ret = argon2_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" - "$8iIuixkI73Js3G1uMbezQXD0b8LG4SXGsOwoQkdAQIM", - "password", strlen("password"), Argon2_i); - assert(ret == ARGON2_VERIFY_MISMATCH); - printf("Verify with mismatched password: PASS\n"); - - msg = argon2_error_message(ARGON2_DECODING_FAIL); - assert(strcmp(msg, "Decoding failed") == 0); - printf("Decode an error message: PASS\n\n"); - - printf("Test Argon2id version number: %02x\n", version); - - /* Multiple test cases for various input values */ - hashtest(version, 2, 16, 1, "password", "somesalt", - "09316115d5cf24ed5a15a31a3ba326e5cf32edc24702987c02b6566f61913cf7", - "$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" - "$CTFhFdXPJO1aFaMaO6Mm5c8y7cJHAph8ArZWb2GRPPc", Argon2_id); - hashtest(version, 2, 18, 1, "password", "somesalt", - "78fe1ec91fb3aa5657d72e710854e4c3d9b9198c742f9616c2f085bed95b2e8c", - "$argon2id$v=19$m=262144,t=2,p=1$c29tZXNhbHQ" - "$eP4eyR+zqlZX1y5xCFTkw9m5GYx0L5YWwvCFvtlbLow", Argon2_id); - hashtest(version, 2, 8, 1, "password", "somesalt", - "9dfeb910e80bad0311fee20f9c0e2b12c17987b4cac90c2ef54d5b3021c68bfe", - "$argon2id$v=19$m=256,t=2,p=1$c29tZXNhbHQ" - "$nf65EOgLrQMR/uIPnA4rEsF5h7TKyQwu9U1bMCHGi/4", Argon2_id); - hashtest(version, 2, 8, 2, "password", "somesalt", - "6d093c501fd5999645e0ea3bf620d7b8be7fd2db59c20d9fff9539da2bf57037", - "$argon2id$v=19$m=256,t=2,p=2$c29tZXNhbHQ" - "$bQk8UB/VmZZF4Oo79iDXuL5/0ttZwg2f/5U52iv1cDc", Argon2_id); - hashtest(version, 1, 16, 1, "password", "somesalt", - "f6a5adc1ba723dddef9b5ac1d464e180fcd9dffc9d1cbf76cca2fed795d9ca98", - "$argon2id$v=19$m=65536,t=1,p=1$c29tZXNhbHQ" - "$9qWtwbpyPd3vm1rB1GThgPzZ3/ydHL92zKL+15XZypg", Argon2_id); - hashtest(version, 4, 16, 1, "password", "somesalt", - "9025d48e68ef7395cca9079da4c4ec3affb3c8911fe4f86d1a2520856f63172c", - "$argon2id$v=19$m=65536,t=4,p=1$c29tZXNhbHQ" - "$kCXUjmjvc5XMqQedpMTsOv+zyJEf5PhtGiUghW9jFyw", Argon2_id); - hashtest(version, 2, 16, 1, "differentpassword", "somesalt", - "0b84d652cf6b0c4beaef0dfe278ba6a80df6696281d7e0d2891b817d8c458fde", - "$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" - "$C4TWUs9rDEvq7w3+J4umqA32aWKB1+DSiRuBfYxFj94", Argon2_id); - hashtest(version, 2, 16, 1, "password", "diffsalt", - "bdf32b05ccc42eb15d58fd19b1f856b113da1e9a5874fdcc544308565aa8141c", - "$argon2id$v=19$m=65536,t=2,p=1$ZGlmZnNhbHQ" - "$vfMrBczELrFdWP0ZsfhWsRPaHppYdP3MVEMIVlqoFBw", Argon2_id); - - /* Common error state tests */ - - printf("\n"); - printf("Common error state tests\n"); - - ret = argon2_hash(2, 1, 1, "password", strlen("password"), - "diffsalt", strlen("diffsalt"), - out, OUT_LEN, NULL, 0, Argon2_id, version); - assert(ret == ARGON2_MEMORY_TOO_LITTLE); - printf("Fail on invalid memory: PASS\n"); - - ret = argon2_hash(2, 1 << 12, 1, NULL, strlen("password"), - "diffsalt", strlen("diffsalt"), - out, OUT_LEN, NULL, 0, Argon2_id, version); - assert(ret == ARGON2_PWD_PTR_MISMATCH); - printf("Fail on invalid null pointer: PASS\n"); - - ret = argon2_hash(2, 1 << 12, 1, "password", strlen("password"), "s", 1, - out, OUT_LEN, NULL, 0, Argon2_id, version); - assert(ret == ARGON2_SALT_TOO_SHORT); - printf("Fail on salt too short: PASS\n"); - - return 0; -} diff --git a/Blastproof/keygen/argon2/src/thread.o b/Blastproof/keygen/argon2/src/thread.o deleted file mode 100644 index 0146928..0000000 Binary files a/Blastproof/keygen/argon2/src/thread.o and /dev/null differ diff --git a/Blastproof/keygen/argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj deleted file mode 100644 index 357b4bd..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {CAA75C57-998C-494E-B8A5-5894EF0FC528} - Argon2Opt - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters deleted file mode 100644 index 536602b..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters +++ /dev/null @@ -1,69 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj deleted file mode 100644 index e5ba5b3..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {B3A0FB44-0C1C-4EC3-B155-8B39371F8EE4} - Argon2OptBench - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters deleted file mode 100644 index 0cc0d95..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters +++ /dev/null @@ -1,69 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj deleted file mode 100644 index 71eb33d..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +++ /dev/null @@ -1,230 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {3A898DD8-ACAE-4269-ADFE-EB7260D71583} - Argon2OptDll - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - DynamicLibrary - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters deleted file mode 100644 index c7a7788..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +++ /dev/null @@ -1,66 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj deleted file mode 100644 index 44c97d1..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +++ /dev/null @@ -1,244 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {DBBAAAE6-4560-4D11-8280-30A6650A82EF} - Argon2OptGenKAT - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters deleted file mode 100644 index ff85955..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters +++ /dev/null @@ -1,72 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj deleted file mode 100644 index 43cab0a..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +++ /dev/null @@ -1,235 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {12956597-5E42-433A-93F3-D4EFF50AA207} - Argon2 - 8.1 - Argon2OptTestCI - - - - - v100 - - - $(DefaultPlatformToolset) - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters deleted file mode 100644 index bcd4dab..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters +++ /dev/null @@ -1,69 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj deleted file mode 100644 index a25cd23..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +++ /dev/null @@ -1,243 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {B9CAC9CE-9F0D-4F52-8D67-FDBBAFCD0DE2} - Argon2Ref - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - ProgramDatabase - - - true - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - ProgramDatabase - - - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - ProgramDatabase - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - ProgramDatabase - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - ProgramDatabase - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - ProgramDatabase - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters deleted file mode 100644 index 379cf2e..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters +++ /dev/null @@ -1,69 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj deleted file mode 100644 index 0106eb7..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {99203F6A-6E8C-42FC-8C7C-C07E8913D539} - Argon2RefBench - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters deleted file mode 100644 index 222279a..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters +++ /dev/null @@ -1,69 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj deleted file mode 100644 index 623aaac..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +++ /dev/null @@ -1,230 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {19D911A1-533C-4475-B313-F372481A35D4} - Argon2RefDll - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - DynamicLibrary - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - DynamicLibrary - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters deleted file mode 100644 index ad43f91..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +++ /dev/null @@ -1,66 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj deleted file mode 100644 index f591439..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +++ /dev/null @@ -1,232 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {71921B4C-A795-4A37-95A3-99D600E01211} - Argon2RefGenKAT - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - $(SolutionDir)include;$(IncludePath) - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;GENKAT;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters deleted file mode 100644 index 8490c8a..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters +++ /dev/null @@ -1,72 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Blastproof/keygen/argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj b/Blastproof/keygen/argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj deleted file mode 100644 index 9e9fa08..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Debug - Win32 - - - ReleaseStatic - Win32 - - - ReleaseStatic - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {8A1F7F84-34AF-4DB2-9D58-D4823DFE79E9} - Argon2RefTestCI - 8.1 - - - - - v100 - - - $(DefaultPlatformToolset) - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - $(SolutionDir)include;$(IncludePath) - $(SolutionDir)vs2015\build\ - $(SolutionDir)vs2015\build\$(ProjectName)\ - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - Disabled - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - true - - - - - Level3 - MaxSpeed - true - true - true - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Blastproof/keygen/argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters b/Blastproof/keygen/argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters deleted file mode 100644 index 32bca82..0000000 --- a/Blastproof/keygen/argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters +++ /dev/null @@ -1,69 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/Blastproof/keygen/fors.c b/Blastproof/keygen/fors.c deleted file mode 100644 index e6aa4b4..0000000 --- a/Blastproof/keygen/fors.c +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include - -#include "fors.h" -#include "utils.h" -#include "utilsx1.h" -#include "hash.h" -#include "thash.h" -#include "address.h" - -static void fors_gen_sk(unsigned char *sk, const spx_ctx *ctx, - uint32_t fors_leaf_addr[8]) -{ - prf_addr(sk, ctx, fors_leaf_addr); -} - -static void fors_sk_to_leaf(unsigned char *leaf, const unsigned char *sk, - const spx_ctx *ctx, - uint32_t fors_leaf_addr[8]) -{ - thash(leaf, sk, 1, ctx, fors_leaf_addr); -} - -struct fors_gen_leaf_info { - uint32_t leaf_addrx[8]; -}; - -static void fors_gen_leafx1(unsigned char *leaf, - const spx_ctx *ctx, - uint32_t addr_idx, void *info) -{ - struct fors_gen_leaf_info *fors_info = info; - uint32_t *fors_leaf_addr = fors_info->leaf_addrx; - - /* Only set the parts that the caller doesn't set */ - set_tree_index(fors_leaf_addr, addr_idx); - set_type(fors_leaf_addr, SPX_ADDR_TYPE_FORSPRF); - fors_gen_sk(leaf, ctx, fors_leaf_addr); - - set_type(fors_leaf_addr, SPX_ADDR_TYPE_FORSTREE); - fors_sk_to_leaf(leaf, leaf, - ctx, fors_leaf_addr); -} - -/** - * Interprets m as SPX_FORS_HEIGHT-bit unsigned integers. - * Assumes m contains at least SPX_FORS_HEIGHT * SPX_FORS_TREES bits. - * Assumes indices has space for SPX_FORS_TREES integers. - */ -static void message_to_indices(uint32_t *indices, const unsigned char *m) -{ - unsigned int i, j; - unsigned int offset = 0; - - for (i = 0; i < SPX_FORS_TREES; i++) { - indices[i] = 0; - for (j = 0; j < SPX_FORS_HEIGHT; j++) { - indices[i] ^= ((m[offset >> 3] >> (offset & 0x7)) & 1u) << j; - offset++; - } - } -} - -/** - * Signs a message m, deriving the secret key from sk_seed and the FTS address. - * Assumes m contains at least SPX_FORS_HEIGHT * SPX_FORS_TREES bits. - */ -void fors_sign(unsigned char *sig, unsigned char *pk, - const unsigned char *m, - const spx_ctx *ctx, - const uint32_t fors_addr[8]) -{ - uint32_t indices[SPX_FORS_TREES]; - unsigned char roots[SPX_FORS_TREES * SPX_N]; - uint32_t fors_tree_addr[8] = {0}; - struct fors_gen_leaf_info fors_info = {0}; - uint32_t *fors_leaf_addr = fors_info.leaf_addrx; - uint32_t fors_pk_addr[8] = {0}; - uint32_t idx_offset; - unsigned int i; - - copy_keypair_addr(fors_tree_addr, fors_addr); - copy_keypair_addr(fors_leaf_addr, fors_addr); - - copy_keypair_addr(fors_pk_addr, fors_addr); - set_type(fors_pk_addr, SPX_ADDR_TYPE_FORSPK); - - message_to_indices(indices, m); - - for (i = 0; i < SPX_FORS_TREES; i++) { - idx_offset = i * (1 << SPX_FORS_HEIGHT); - - set_tree_height(fors_tree_addr, 0); - set_tree_index(fors_tree_addr, indices[i] + idx_offset); - set_type(fors_tree_addr, SPX_ADDR_TYPE_FORSPRF); - - /* Include the secret key part that produces the selected leaf node. */ - fors_gen_sk(sig, ctx, fors_tree_addr); - set_type(fors_tree_addr, SPX_ADDR_TYPE_FORSTREE); - sig += SPX_N; - - /* Compute the authentication path for this leaf node. */ - treehashx1(roots + i*SPX_N, sig, ctx, - indices[i], idx_offset, SPX_FORS_HEIGHT, fors_gen_leafx1, - fors_tree_addr, &fors_info); - - sig += SPX_N * SPX_FORS_HEIGHT; - } - - /* Hash horizontally across all tree roots to derive the public key. */ - thash(pk, roots, SPX_FORS_TREES, ctx, fors_pk_addr); -} - -/** - * Derives the FORS public key from a signature. - * This can be used for verification by comparing to a known public key, or to - * subsequently verify a signature on the derived public key. The latter is the - * typical use-case when used as an FTS below an OTS in a hypertree. - * Assumes m contains at least SPX_FORS_HEIGHT * SPX_FORS_TREES bits. - */ -void fors_pk_from_sig(unsigned char *pk, - const unsigned char *sig, const unsigned char *m, - const spx_ctx* ctx, - const uint32_t fors_addr[8]) -{ - uint32_t indices[SPX_FORS_TREES]; - unsigned char roots[SPX_FORS_TREES * SPX_N]; - unsigned char leaf[SPX_N]; - uint32_t fors_tree_addr[8] = {0}; - uint32_t fors_pk_addr[8] = {0}; - uint32_t idx_offset; - unsigned int i; - - copy_keypair_addr(fors_tree_addr, fors_addr); - copy_keypair_addr(fors_pk_addr, fors_addr); - - set_type(fors_tree_addr, SPX_ADDR_TYPE_FORSTREE); - set_type(fors_pk_addr, SPX_ADDR_TYPE_FORSPK); - - message_to_indices(indices, m); - - for (i = 0; i < SPX_FORS_TREES; i++) { - idx_offset = i * (1 << SPX_FORS_HEIGHT); - - set_tree_height(fors_tree_addr, 0); - set_tree_index(fors_tree_addr, indices[i] + idx_offset); - - /* Derive the leaf from the included secret key part. */ - fors_sk_to_leaf(leaf, sig, ctx, fors_tree_addr); - sig += SPX_N; - - /* Derive the corresponding root node of this tree. */ - compute_root(roots + i*SPX_N, leaf, indices[i], idx_offset, - sig, SPX_FORS_HEIGHT, ctx, fors_tree_addr); - sig += SPX_N * SPX_FORS_HEIGHT; - } - - /* Hash horizontally across all tree roots to derive the public key. */ - thash(pk, roots, SPX_FORS_TREES, ctx, fors_pk_addr); -} diff --git a/Blastproof/keygen/fors.o b/Blastproof/keygen/fors.o deleted file mode 100644 index 20cd3d9..0000000 Binary files a/Blastproof/keygen/fors.o and /dev/null differ diff --git a/Blastproof/keygen/hash_sha2.c b/Blastproof/keygen/hash_sha2.c deleted file mode 100644 index 67098e6..0000000 --- a/Blastproof/keygen/hash_sha2.c +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include - -#include "address.h" -#include "utils.h" -#include "params.h" -#include "hash.h" -#include "sha2.h" - -#if SPX_N >= 24 -#define SPX_SHAX_OUTPUT_BYTES SPX_SHA512_OUTPUT_BYTES -#define SPX_SHAX_BLOCK_BYTES SPX_SHA512_BLOCK_BYTES -#define shaX_inc_init sha512_inc_init -#define shaX_inc_blocks sha512_inc_blocks -#define shaX_inc_finalize sha512_inc_finalize -#define shaX sha512 -#define mgf1_X mgf1_512 -#else -#define SPX_SHAX_OUTPUT_BYTES SPX_SHA256_OUTPUT_BYTES -#define SPX_SHAX_BLOCK_BYTES SPX_SHA256_BLOCK_BYTES -#define shaX_inc_init sha256_inc_init -#define shaX_inc_blocks sha256_inc_blocks -#define shaX_inc_finalize sha256_inc_finalize -#define shaX sha256 -#define mgf1_X mgf1_256 -#endif - - -/* For SHA, there is no immediate reason to initialize at the start, - so this function is an empty operation. */ -void initialize_hash_function(spx_ctx *ctx) -{ - seed_state(ctx); -} - -/* - * Computes PRF(pk_seed, sk_seed, addr). - */ -void prf_addr(unsigned char *out, const spx_ctx *ctx, - const uint32_t addr[8]) -{ - uint8_t sha2_state[40]; - unsigned char buf[SPX_SHA256_ADDR_BYTES + SPX_N]; - unsigned char outbuf[SPX_SHA256_OUTPUT_BYTES]; - - /* Retrieve precomputed state containing pub_seed */ - memcpy(sha2_state, ctx->state_seeded, 40 * sizeof(uint8_t)); - - /* Remainder: ADDR^c ‖ SK.seed */ - memcpy(buf, addr, SPX_SHA256_ADDR_BYTES); - memcpy(buf + SPX_SHA256_ADDR_BYTES, ctx->sk_seed, SPX_N); - - sha256_inc_finalize(outbuf, sha2_state, buf, SPX_SHA256_ADDR_BYTES + SPX_N); - - memcpy(out, outbuf, SPX_N); -} - -/** - * Computes the message-dependent randomness R, using a secret seed as a key - * for HMAC, and an optional randomization value prefixed to the message. - * This requires m to have at least SPX_SHAX_BLOCK_BYTES + SPX_N space - * available in front of the pointer, i.e. before the message to use for the - * prefix. This is necessary to prevent having to move the message around (and - * allocate memory for it). - */ -void gen_message_random(unsigned char *R, const unsigned char *sk_prf, - const unsigned char *optrand, - const unsigned char *m, unsigned long long mlen, - const spx_ctx *ctx) -{ - (void)ctx; - - unsigned char buf[SPX_SHAX_BLOCK_BYTES + SPX_SHAX_OUTPUT_BYTES]; - uint8_t state[8 + SPX_SHAX_OUTPUT_BYTES]; - int i; - -#if SPX_N > SPX_SHAX_BLOCK_BYTES - #error "Currently only supports SPX_N of at most SPX_SHAX_BLOCK_BYTES" -#endif - - /* This implements HMAC-SHA */ - for (i = 0; i < SPX_N; i++) { - buf[i] = 0x36 ^ sk_prf[i]; - } - memset(buf + SPX_N, 0x36, SPX_SHAX_BLOCK_BYTES - SPX_N); - - shaX_inc_init(state); - shaX_inc_blocks(state, buf, 1); - - memcpy(buf, optrand, SPX_N); - - /* If optrand + message cannot fill up an entire block */ - if (SPX_N + mlen < SPX_SHAX_BLOCK_BYTES) { - memcpy(buf + SPX_N, m, mlen); - shaX_inc_finalize(buf + SPX_SHAX_BLOCK_BYTES, state, - buf, mlen + SPX_N); - } - /* Otherwise first fill a block, so that finalize only uses the message */ - else { - memcpy(buf + SPX_N, m, SPX_SHAX_BLOCK_BYTES - SPX_N); - shaX_inc_blocks(state, buf, 1); - - m += SPX_SHAX_BLOCK_BYTES - SPX_N; - mlen -= SPX_SHAX_BLOCK_BYTES - SPX_N; - shaX_inc_finalize(buf + SPX_SHAX_BLOCK_BYTES, state, m, mlen); - } - - for (i = 0; i < SPX_N; i++) { - buf[i] = 0x5c ^ sk_prf[i]; - } - memset(buf + SPX_N, 0x5c, SPX_SHAX_BLOCK_BYTES - SPX_N); - - shaX(buf, buf, SPX_SHAX_BLOCK_BYTES + SPX_SHAX_OUTPUT_BYTES); - memcpy(R, buf, SPX_N); -} - -/** - * Computes the message hash using R, the public key, and the message. - * Outputs the message digest and the index of the leaf. The index is split in - * the tree index and the leaf index, for convenient copying to an address. - */ -void hash_message(unsigned char *digest, uint64_t *tree, uint32_t *leaf_idx, - const unsigned char *R, const unsigned char *pk, - const unsigned char *m, unsigned long long mlen, - const spx_ctx *ctx) -{ - (void)ctx; -#define SPX_TREE_BITS (SPX_TREE_HEIGHT * (SPX_D - 1)) -#define SPX_TREE_BYTES ((SPX_TREE_BITS + 7) / 8) -#define SPX_LEAF_BITS SPX_TREE_HEIGHT -#define SPX_LEAF_BYTES ((SPX_LEAF_BITS + 7) / 8) -#define SPX_DGST_BYTES (SPX_FORS_MSG_BYTES + SPX_TREE_BYTES + SPX_LEAF_BYTES) - - unsigned char seed[2*SPX_N + SPX_SHAX_OUTPUT_BYTES]; - - /* Round to nearest multiple of SPX_SHAX_BLOCK_BYTES */ -#if (SPX_SHAX_BLOCK_BYTES & (SPX_SHAX_BLOCK_BYTES-1)) != 0 - #error "Assumes that SPX_SHAX_BLOCK_BYTES is a power of 2" -#endif -#define SPX_INBLOCKS (((SPX_N + SPX_PK_BYTES + SPX_SHAX_BLOCK_BYTES - 1) & \ - -SPX_SHAX_BLOCK_BYTES) / SPX_SHAX_BLOCK_BYTES) - unsigned char inbuf[SPX_INBLOCKS * SPX_SHAX_BLOCK_BYTES]; - - unsigned char buf[SPX_DGST_BYTES]; - unsigned char *bufp = buf; - uint8_t state[8 + SPX_SHAX_OUTPUT_BYTES]; - - shaX_inc_init(state); - - // seed: SHA-X(R ‖ PK.seed ‖ PK.root ‖ M) - memcpy(inbuf, R, SPX_N); - memcpy(inbuf + SPX_N, pk, SPX_PK_BYTES); - - /* If R + pk + message cannot fill up an entire block */ - if (SPX_N + SPX_PK_BYTES + mlen < SPX_INBLOCKS * SPX_SHAX_BLOCK_BYTES) { - memcpy(inbuf + SPX_N + SPX_PK_BYTES, m, mlen); - shaX_inc_finalize(seed + 2*SPX_N, state, inbuf, SPX_N + SPX_PK_BYTES + mlen); - } - /* Otherwise first fill a block, so that finalize only uses the message */ - else { - memcpy(inbuf + SPX_N + SPX_PK_BYTES, m, - SPX_INBLOCKS * SPX_SHAX_BLOCK_BYTES - SPX_N - SPX_PK_BYTES); - shaX_inc_blocks(state, inbuf, SPX_INBLOCKS); - - m += SPX_INBLOCKS * SPX_SHAX_BLOCK_BYTES - SPX_N - SPX_PK_BYTES; - mlen -= SPX_INBLOCKS * SPX_SHAX_BLOCK_BYTES - SPX_N - SPX_PK_BYTES; - shaX_inc_finalize(seed + 2*SPX_N, state, m, mlen); - } - - // H_msg: MGF1-SHA-X(R ‖ PK.seed ‖ seed) - memcpy(seed, R, SPX_N); - memcpy(seed + SPX_N, pk, SPX_N); - - /* By doing this in two steps, we prevent hashing the message twice; - otherwise each iteration in MGF1 would hash the message again. */ - mgf1_X(bufp, SPX_DGST_BYTES, seed, 2*SPX_N + SPX_SHAX_OUTPUT_BYTES); - - memcpy(digest, bufp, SPX_FORS_MSG_BYTES); - bufp += SPX_FORS_MSG_BYTES; - -#if SPX_TREE_BITS > 64 - #error For given height and depth, 64 bits cannot represent all subtrees -#endif - - if (SPX_D == 1) { - *tree = 0; - } else { - *tree = bytes_to_ull(bufp, SPX_TREE_BYTES); - *tree &= (~(uint64_t)0) >> (64 - SPX_TREE_BITS); - } - bufp += SPX_TREE_BYTES; - - *leaf_idx = (uint32_t)bytes_to_ull(bufp, SPX_LEAF_BYTES); - *leaf_idx &= (~(uint32_t)0) >> (32 - SPX_LEAF_BITS); -} - - diff --git a/Blastproof/keygen/hash_sha2.o b/Blastproof/keygen/hash_sha2.o deleted file mode 100644 index 7bafb7b..0000000 Binary files a/Blastproof/keygen/hash_sha2.o and /dev/null differ diff --git a/Blastproof/keygen/keygen-run.json b/Blastproof/keygen/keygen-run.json new file mode 100644 index 0000000..2bf0a32 --- /dev/null +++ b/Blastproof/keygen/keygen-run.json @@ -0,0 +1,36 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Keygen execution", + "actions":[ + { + "action":"vftm_run_key_generator", + "args":{ + "command_variables":true, + "command":[ + "bash", + "-c", + "VYSTEM_KEYGEN_PASSWORD=\"$VYSTEM_KEYGEN_PASSWORD$\" sudo -E ./keygen/keygen ./config/bp.cfg ./fontgen/font.fbm ./initfsgen/initfsfp.bin ./initfsgen/sshash.bin" + ], + "success_status":[ + 0 + ], + "ignore_success_status":false, + "working_dir_variables":true, + "working_dir":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$", + "socket_path_variables":true, + "socket_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/vftm.sock" + } + }, + { + "action":"move_file", + "args":{ + "source_file_variables":true, + "source_file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/key.h", + "destination_folder_variables":true, + "destination_folder":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/src/libs/include" + } + } + ] +} diff --git a/Blastproof/keygen/keygen.cpp b/Blastproof/keygen/keygen.cpp index c04e224..e9ddde5 100644 --- a/Blastproof/keygen/keygen.cpp +++ b/Blastproof/keygen/keygen.cpp @@ -7,79 +7,22 @@ extern "C" { #include "sha3.h" } #undef str +#include +#include #include +#include #include #include #include #include -#include #include +#include #include #include #include #include -#include using namespace std; namespace fs=filesystem; -const map azerty_to_qwerty={ - {"a","q"}, - {"A","Q"}, - {"z","w"}, - {"Z","W"}, - {"q","a"}, - {"Q","A"}, - {"m",";"}, - {"M",":"}, - {"w","z"}, - {"W","Z"}, - {",","m"}, - {"?","M"}, - {"²","`"}, - {"&","1"}, - {"é","2"}, - {"\"","3"}, - {"'","4"}, - {"(","5"}, - {"-","6"}, - {"è","7"}, - {"_","8"}, - {"ç","9"}, - {"à","0"}, - {"~","2"}, - {"#","3"}, - {"{","4"}, - {"[","5"}, - {"|","6"}, - {"`","7"}, - {"\\","8"}, - {"^","9"}, - {"@","0"}, - {"1","!"}, - {"2","@"}, - {"3","#"}, - {"4","$"}, - {"5","%"}, - {"6","^"}, - {"7","&"}, - {"8","*"}, - {"9","("}, - {"0",")"}, - {";",","}, - {".","<"}, - {":","."}, - {"/",">"}, - {"!","/"}, - {"§","?"}, - {"<","\\"}, - {">","|"}, - {"ù","'"}, - {"%","\""}, - {"^","["}, - {"¨","{"}, - {"$","]"}, - {"£","}"}, - {"µ","|"} -}; void secure_erase(void *address,size_t size) { explicit_bzero(address,size); } @@ -118,6 +61,115 @@ int main(int argc,char **argv) { cout<<"[Keygen] Error: can't setup security."< files; if (argc>1) { for (int i=1;i(sigsbuf.data()+i*CRYPTO_BYTES),CRYPTO_BYTES); sigfile.close(); + if (set_files_to_user && user_info) { + if (chown(sigpath.c_str(),user_info->pw_uid,user_info->pw_gid)!=0) { + cout<<"[Keygen] Warning: couldn't change file "< passhex; + passhex.resize(num); + try { + passhex=get_urandom(num); + } catch (const exception e) { + if (string(e.what())=="open") { + cout<<"[Keygen] Error: can't open secure source of randomness."<(byte); + } + password=oss.str(); + secure_erase(passhex.data(),passhex.size()); + } else if (strlen(pwd)<=512){ + password=string(pwd); + char* confirm_pwd=getpass("[Keygen] Confirm password: "); + string confirm_password(confirm_pwd); + if (confirm_password!=password) { + cout<<"[Keygen] Error: password don't correspond. Please try again."< passhex; - passhex.resize(num); - try { - passhex=get_urandom(num); - } catch (const exception e) { - if (string(e.what())=="open") { - cout<<"[Keygen] Error: can't open secure source of randomness."<=0x80) { + cout<<"[Keygen] Error: one character isn't ASCII."<(byte); - } - password=oss.str(); - secure_erase(passhex.data(),passhex.size()); - } else if (strlen(pwd)<=512){ - password=string(pwd); - char* confirm_pwd=getpass("[Keygen] Confirm password: "); - string confirm_password(confirm_pwd); - if (confirm_password!=password) { - cout<<"[Keygen] Error: password don't correspond. Please try again."<=0x80) { + cout<<"[Keygen] Error: one character isn't ASCII."<=0x80) { - cout<<"[Keygen] Error: one character isn't ASCII."< passutf16(password.size()*2); @@ -339,7 +378,6 @@ int main(int argc,char **argv) { } secure_erase(pk,sizeof(pk)); secure_erase(seed.data(),seed.size()); - size_t siglen; if (crypto_sign_signature(sig,&siglen,pksbuf.data(),pksbuf.size(),sk)!=0) { cout<<"[Keygen] Error: can't generate signature from all publics keys."<pw_uid,user_info->pw_gid)!=0) { + cout<<"[Keygen] Warning: couldn't change file \""<pw_uid,user_info->pw_gid)!=0) { + cout<<"[Keygen] Warning: couldn't change file \""< -#include - -#include "utils.h" -#include "utilsx1.h" -#include "wots.h" -#include "wotsx1.h" -#include "merkle.h" -#include "address.h" -#include "params.h" - -/* - * This generates a Merkle signature (WOTS signature followed by the Merkle - * authentication path). This is in this file because most of the complexity - * is involved with the WOTS signature; the Merkle authentication path logic - * is mostly hidden in treehashx4 - */ -void merkle_sign(uint8_t *sig, unsigned char *root, - const spx_ctx *ctx, - uint32_t wots_addr[8], uint32_t tree_addr[8], - uint32_t idx_leaf) -{ - unsigned char *auth_path = sig + SPX_WOTS_BYTES; - struct leaf_info_x1 info = { 0 }; - unsigned steps[ SPX_WOTS_LEN ]; - - info.wots_sig = sig; - chain_lengths(steps, root); - info.wots_steps = steps; - - set_type(&tree_addr[0], SPX_ADDR_TYPE_HASHTREE); - set_type(&info.pk_addr[0], SPX_ADDR_TYPE_WOTSPK); - copy_subtree_addr(&info.leaf_addr[0], wots_addr); - copy_subtree_addr(&info.pk_addr[0], wots_addr); - - info.wots_sign_leaf = idx_leaf; - - treehashx1(root, auth_path, ctx, - idx_leaf, 0, - SPX_TREE_HEIGHT, - wots_gen_leafx1, - tree_addr, &info); -} - -/* Compute root node of the top-most subtree. */ -void merkle_gen_root(unsigned char *root, const spx_ctx *ctx) -{ - /* We do not need the auth path in key generation, but it simplifies the - code to have just one treehash routine that computes both root and path - in one function. */ - unsigned char auth_path[SPX_TREE_HEIGHT * SPX_N + SPX_WOTS_BYTES]; - uint32_t top_tree_addr[8] = {0}; - uint32_t wots_addr[8] = {0}; - - set_layer_addr(top_tree_addr, SPX_D - 1); - set_layer_addr(wots_addr, SPX_D - 1); - - merkle_sign(auth_path, root, ctx, - wots_addr, top_tree_addr, - (uint32_t)~0 /* ~0 means "don't bother generating an auth path */ ); -} diff --git a/Blastproof/keygen/merkle.o b/Blastproof/keygen/merkle.o deleted file mode 100644 index 0146c87..0000000 Binary files a/Blastproof/keygen/merkle.o and /dev/null differ diff --git a/Blastproof/keygen/randombytes.c b/Blastproof/keygen/randombytes.c deleted file mode 100644 index cfbca17..0000000 --- a/Blastproof/keygen/randombytes.c +++ /dev/null @@ -1,43 +0,0 @@ -/* -This code was taken from the SPHINCS reference implementation and is public domain. -*/ - -#include -#include - -#include "randombytes.h" - -static int fd = -1; - -void randombytes(unsigned char *x, unsigned long long xlen) -{ - unsigned long long i; - - if (fd == -1) { - for (;;) { - fd = open("/dev/urandom", O_RDONLY); - if (fd != -1) { - break; - } - sleep(1); - } - } - - while (xlen > 0) { - if (xlen < 1048576) { - i = xlen; - } - else { - i = 1048576; - } - - i = (unsigned long long)read(fd, x, i); - if (i < 1) { - sleep(1); - continue; - } - - x += i; - xlen -= i; - } -} diff --git a/Blastproof/keygen/randombytes.o b/Blastproof/keygen/randombytes.o deleted file mode 100644 index 26c3531..0000000 Binary files a/Blastproof/keygen/randombytes.o and /dev/null differ diff --git a/Blastproof/keygen/sha2.c b/Blastproof/keygen/sha2.c deleted file mode 100644 index ef73047..0000000 --- a/Blastproof/keygen/sha2.c +++ /dev/null @@ -1,700 +0,0 @@ -/* Based on the public domain implementation in - * crypto_hash/sha512/ref/ from http://bench.cr.yp.to/supercop.html - * by D. J. Bernstein */ - -#include -#include -#include - -#include "utils.h" -#include "sha2.h" - -static uint32_t load_bigendian_32(const uint8_t *x) { - return (uint32_t)(x[3]) | (((uint32_t)(x[2])) << 8) | - (((uint32_t)(x[1])) << 16) | (((uint32_t)(x[0])) << 24); -} - -static uint64_t load_bigendian_64(const uint8_t *x) { - return (uint64_t)(x[7]) | (((uint64_t)(x[6])) << 8) | - (((uint64_t)(x[5])) << 16) | (((uint64_t)(x[4])) << 24) | - (((uint64_t)(x[3])) << 32) | (((uint64_t)(x[2])) << 40) | - (((uint64_t)(x[1])) << 48) | (((uint64_t)(x[0])) << 56); -} - -static void store_bigendian_32(uint8_t *x, uint64_t u) { - x[3] = (uint8_t) u; - u >>= 8; - x[2] = (uint8_t) u; - u >>= 8; - x[1] = (uint8_t) u; - u >>= 8; - x[0] = (uint8_t) u; -} - -static void store_bigendian_64(uint8_t *x, uint64_t u) { - x[7] = (uint8_t) u; - u >>= 8; - x[6] = (uint8_t) u; - u >>= 8; - x[5] = (uint8_t) u; - u >>= 8; - x[4] = (uint8_t) u; - u >>= 8; - x[3] = (uint8_t) u; - u >>= 8; - x[2] = (uint8_t) u; - u >>= 8; - x[1] = (uint8_t) u; - u >>= 8; - x[0] = (uint8_t) u; -} - -#define SHR(x, c) ((x) >> (c)) -#define ROTR_32(x, c) (((x) >> (c)) | ((x) << (32 - (c)))) -#define ROTR_64(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) - -#define Ch(x, y, z) (((x) & (y)) ^ (~(x) & (z))) -#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -#define Sigma0_32(x) (ROTR_32(x, 2) ^ ROTR_32(x,13) ^ ROTR_32(x,22)) -#define Sigma1_32(x) (ROTR_32(x, 6) ^ ROTR_32(x,11) ^ ROTR_32(x,25)) -#define sigma0_32(x) (ROTR_32(x, 7) ^ ROTR_32(x,18) ^ SHR(x, 3)) -#define sigma1_32(x) (ROTR_32(x,17) ^ ROTR_32(x,19) ^ SHR(x,10)) - -#define Sigma0_64(x) (ROTR_64(x,28) ^ ROTR_64(x,34) ^ ROTR_64(x,39)) -#define Sigma1_64(x) (ROTR_64(x,14) ^ ROTR_64(x,18) ^ ROTR_64(x,41)) -#define sigma0_64(x) (ROTR_64(x, 1) ^ ROTR_64(x, 8) ^ SHR(x,7)) -#define sigma1_64(x) (ROTR_64(x,19) ^ ROTR_64(x,61) ^ SHR(x,6)) - -#define M_32(w0, w14, w9, w1) w0 = sigma1_32(w14) + (w9) + sigma0_32(w1) + (w0); -#define M_64(w0, w14, w9, w1) w0 = sigma1_64(w14) + (w9) + sigma0_64(w1) + (w0); - -#define EXPAND_32 \ - M_32(w0, w14, w9, w1) \ - M_32(w1, w15, w10, w2) \ - M_32(w2, w0, w11, w3) \ - M_32(w3, w1, w12, w4) \ - M_32(w4, w2, w13, w5) \ - M_32(w5, w3, w14, w6) \ - M_32(w6, w4, w15, w7) \ - M_32(w7, w5, w0, w8) \ - M_32(w8, w6, w1, w9) \ - M_32(w9, w7, w2, w10) \ - M_32(w10, w8, w3, w11) \ - M_32(w11, w9, w4, w12) \ - M_32(w12, w10, w5, w13) \ - M_32(w13, w11, w6, w14) \ - M_32(w14, w12, w7, w15) \ - M_32(w15, w13, w8, w0) - -#define EXPAND_64 \ - M_64(w0 ,w14,w9 ,w1 ) \ - M_64(w1 ,w15,w10,w2 ) \ - M_64(w2 ,w0 ,w11,w3 ) \ - M_64(w3 ,w1 ,w12,w4 ) \ - M_64(w4 ,w2 ,w13,w5 ) \ - M_64(w5 ,w3 ,w14,w6 ) \ - M_64(w6 ,w4 ,w15,w7 ) \ - M_64(w7 ,w5 ,w0 ,w8 ) \ - M_64(w8 ,w6 ,w1 ,w9 ) \ - M_64(w9 ,w7 ,w2 ,w10) \ - M_64(w10,w8 ,w3 ,w11) \ - M_64(w11,w9 ,w4 ,w12) \ - M_64(w12,w10,w5 ,w13) \ - M_64(w13,w11,w6 ,w14) \ - M_64(w14,w12,w7 ,w15) \ - M_64(w15,w13,w8 ,w0 ) - -#define F_32(w, k) \ - T1 = h + Sigma1_32(e) + Ch(e, f, g) + (k) + (w); \ - T2 = Sigma0_32(a) + Maj(a, b, c); \ - h = g; \ - g = f; \ - f = e; \ - e = d + T1; \ - d = c; \ - c = b; \ - b = a; \ - a = T1 + T2; - -#define F_64(w,k) \ - T1 = h + Sigma1_64(e) + Ch(e,f,g) + k + w; \ - T2 = Sigma0_64(a) + Maj(a,b,c); \ - h = g; \ - g = f; \ - f = e; \ - e = d + T1; \ - d = c; \ - c = b; \ - b = a; \ - a = T1 + T2; - -static size_t crypto_hashblocks_sha256(uint8_t *statebytes, - const uint8_t *in, size_t inlen) { - uint32_t state[8]; - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; - uint32_t e; - uint32_t f; - uint32_t g; - uint32_t h; - uint32_t T1; - uint32_t T2; - - a = load_bigendian_32(statebytes + 0); - state[0] = a; - b = load_bigendian_32(statebytes + 4); - state[1] = b; - c = load_bigendian_32(statebytes + 8); - state[2] = c; - d = load_bigendian_32(statebytes + 12); - state[3] = d; - e = load_bigendian_32(statebytes + 16); - state[4] = e; - f = load_bigendian_32(statebytes + 20); - state[5] = f; - g = load_bigendian_32(statebytes + 24); - state[6] = g; - h = load_bigendian_32(statebytes + 28); - state[7] = h; - - while (inlen >= 64) { - uint32_t w0 = load_bigendian_32(in + 0); - uint32_t w1 = load_bigendian_32(in + 4); - uint32_t w2 = load_bigendian_32(in + 8); - uint32_t w3 = load_bigendian_32(in + 12); - uint32_t w4 = load_bigendian_32(in + 16); - uint32_t w5 = load_bigendian_32(in + 20); - uint32_t w6 = load_bigendian_32(in + 24); - uint32_t w7 = load_bigendian_32(in + 28); - uint32_t w8 = load_bigendian_32(in + 32); - uint32_t w9 = load_bigendian_32(in + 36); - uint32_t w10 = load_bigendian_32(in + 40); - uint32_t w11 = load_bigendian_32(in + 44); - uint32_t w12 = load_bigendian_32(in + 48); - uint32_t w13 = load_bigendian_32(in + 52); - uint32_t w14 = load_bigendian_32(in + 56); - uint32_t w15 = load_bigendian_32(in + 60); - - F_32(w0, 0x428a2f98) - F_32(w1, 0x71374491) - F_32(w2, 0xb5c0fbcf) - F_32(w3, 0xe9b5dba5) - F_32(w4, 0x3956c25b) - F_32(w5, 0x59f111f1) - F_32(w6, 0x923f82a4) - F_32(w7, 0xab1c5ed5) - F_32(w8, 0xd807aa98) - F_32(w9, 0x12835b01) - F_32(w10, 0x243185be) - F_32(w11, 0x550c7dc3) - F_32(w12, 0x72be5d74) - F_32(w13, 0x80deb1fe) - F_32(w14, 0x9bdc06a7) - F_32(w15, 0xc19bf174) - - EXPAND_32 - - F_32(w0, 0xe49b69c1) - F_32(w1, 0xefbe4786) - F_32(w2, 0x0fc19dc6) - F_32(w3, 0x240ca1cc) - F_32(w4, 0x2de92c6f) - F_32(w5, 0x4a7484aa) - F_32(w6, 0x5cb0a9dc) - F_32(w7, 0x76f988da) - F_32(w8, 0x983e5152) - F_32(w9, 0xa831c66d) - F_32(w10, 0xb00327c8) - F_32(w11, 0xbf597fc7) - F_32(w12, 0xc6e00bf3) - F_32(w13, 0xd5a79147) - F_32(w14, 0x06ca6351) - F_32(w15, 0x14292967) - - EXPAND_32 - - F_32(w0, 0x27b70a85) - F_32(w1, 0x2e1b2138) - F_32(w2, 0x4d2c6dfc) - F_32(w3, 0x53380d13) - F_32(w4, 0x650a7354) - F_32(w5, 0x766a0abb) - F_32(w6, 0x81c2c92e) - F_32(w7, 0x92722c85) - F_32(w8, 0xa2bfe8a1) - F_32(w9, 0xa81a664b) - F_32(w10, 0xc24b8b70) - F_32(w11, 0xc76c51a3) - F_32(w12, 0xd192e819) - F_32(w13, 0xd6990624) - F_32(w14, 0xf40e3585) - F_32(w15, 0x106aa070) - - EXPAND_32 - - F_32(w0, 0x19a4c116) - F_32(w1, 0x1e376c08) - F_32(w2, 0x2748774c) - F_32(w3, 0x34b0bcb5) - F_32(w4, 0x391c0cb3) - F_32(w5, 0x4ed8aa4a) - F_32(w6, 0x5b9cca4f) - F_32(w7, 0x682e6ff3) - F_32(w8, 0x748f82ee) - F_32(w9, 0x78a5636f) - F_32(w10, 0x84c87814) - F_32(w11, 0x8cc70208) - F_32(w12, 0x90befffa) - F_32(w13, 0xa4506ceb) - F_32(w14, 0xbef9a3f7) - F_32(w15, 0xc67178f2) - - a += state[0]; - b += state[1]; - c += state[2]; - d += state[3]; - e += state[4]; - f += state[5]; - g += state[6]; - h += state[7]; - - state[0] = a; - state[1] = b; - state[2] = c; - state[3] = d; - state[4] = e; - state[5] = f; - state[6] = g; - state[7] = h; - - in += 64; - inlen -= 64; - } - - store_bigendian_32(statebytes + 0, state[0]); - store_bigendian_32(statebytes + 4, state[1]); - store_bigendian_32(statebytes + 8, state[2]); - store_bigendian_32(statebytes + 12, state[3]); - store_bigendian_32(statebytes + 16, state[4]); - store_bigendian_32(statebytes + 20, state[5]); - store_bigendian_32(statebytes + 24, state[6]); - store_bigendian_32(statebytes + 28, state[7]); - - return inlen; -} - -static int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen) -{ - uint64_t state[8]; - uint64_t a; - uint64_t b; - uint64_t c; - uint64_t d; - uint64_t e; - uint64_t f; - uint64_t g; - uint64_t h; - uint64_t T1; - uint64_t T2; - - a = load_bigendian_64(statebytes + 0); state[0] = a; - b = load_bigendian_64(statebytes + 8); state[1] = b; - c = load_bigendian_64(statebytes + 16); state[2] = c; - d = load_bigendian_64(statebytes + 24); state[3] = d; - e = load_bigendian_64(statebytes + 32); state[4] = e; - f = load_bigendian_64(statebytes + 40); state[5] = f; - g = load_bigendian_64(statebytes + 48); state[6] = g; - h = load_bigendian_64(statebytes + 56); state[7] = h; - - while (inlen >= 128) { - uint64_t w0 = load_bigendian_64(in + 0); - uint64_t w1 = load_bigendian_64(in + 8); - uint64_t w2 = load_bigendian_64(in + 16); - uint64_t w3 = load_bigendian_64(in + 24); - uint64_t w4 = load_bigendian_64(in + 32); - uint64_t w5 = load_bigendian_64(in + 40); - uint64_t w6 = load_bigendian_64(in + 48); - uint64_t w7 = load_bigendian_64(in + 56); - uint64_t w8 = load_bigendian_64(in + 64); - uint64_t w9 = load_bigendian_64(in + 72); - uint64_t w10 = load_bigendian_64(in + 80); - uint64_t w11 = load_bigendian_64(in + 88); - uint64_t w12 = load_bigendian_64(in + 96); - uint64_t w13 = load_bigendian_64(in + 104); - uint64_t w14 = load_bigendian_64(in + 112); - uint64_t w15 = load_bigendian_64(in + 120); - - F_64(w0 ,0x428a2f98d728ae22ULL) - F_64(w1 ,0x7137449123ef65cdULL) - F_64(w2 ,0xb5c0fbcfec4d3b2fULL) - F_64(w3 ,0xe9b5dba58189dbbcULL) - F_64(w4 ,0x3956c25bf348b538ULL) - F_64(w5 ,0x59f111f1b605d019ULL) - F_64(w6 ,0x923f82a4af194f9bULL) - F_64(w7 ,0xab1c5ed5da6d8118ULL) - F_64(w8 ,0xd807aa98a3030242ULL) - F_64(w9 ,0x12835b0145706fbeULL) - F_64(w10,0x243185be4ee4b28cULL) - F_64(w11,0x550c7dc3d5ffb4e2ULL) - F_64(w12,0x72be5d74f27b896fULL) - F_64(w13,0x80deb1fe3b1696b1ULL) - F_64(w14,0x9bdc06a725c71235ULL) - F_64(w15,0xc19bf174cf692694ULL) - - EXPAND_64 - - F_64(w0 ,0xe49b69c19ef14ad2ULL) - F_64(w1 ,0xefbe4786384f25e3ULL) - F_64(w2 ,0x0fc19dc68b8cd5b5ULL) - F_64(w3 ,0x240ca1cc77ac9c65ULL) - F_64(w4 ,0x2de92c6f592b0275ULL) - F_64(w5 ,0x4a7484aa6ea6e483ULL) - F_64(w6 ,0x5cb0a9dcbd41fbd4ULL) - F_64(w7 ,0x76f988da831153b5ULL) - F_64(w8 ,0x983e5152ee66dfabULL) - F_64(w9 ,0xa831c66d2db43210ULL) - F_64(w10,0xb00327c898fb213fULL) - F_64(w11,0xbf597fc7beef0ee4ULL) - F_64(w12,0xc6e00bf33da88fc2ULL) - F_64(w13,0xd5a79147930aa725ULL) - F_64(w14,0x06ca6351e003826fULL) - F_64(w15,0x142929670a0e6e70ULL) - - EXPAND_64 - - F_64(w0 ,0x27b70a8546d22ffcULL) - F_64(w1 ,0x2e1b21385c26c926ULL) - F_64(w2 ,0x4d2c6dfc5ac42aedULL) - F_64(w3 ,0x53380d139d95b3dfULL) - F_64(w4 ,0x650a73548baf63deULL) - F_64(w5 ,0x766a0abb3c77b2a8ULL) - F_64(w6 ,0x81c2c92e47edaee6ULL) - F_64(w7 ,0x92722c851482353bULL) - F_64(w8 ,0xa2bfe8a14cf10364ULL) - F_64(w9 ,0xa81a664bbc423001ULL) - F_64(w10,0xc24b8b70d0f89791ULL) - F_64(w11,0xc76c51a30654be30ULL) - F_64(w12,0xd192e819d6ef5218ULL) - F_64(w13,0xd69906245565a910ULL) - F_64(w14,0xf40e35855771202aULL) - F_64(w15,0x106aa07032bbd1b8ULL) - - EXPAND_64 - - F_64(w0 ,0x19a4c116b8d2d0c8ULL) - F_64(w1 ,0x1e376c085141ab53ULL) - F_64(w2 ,0x2748774cdf8eeb99ULL) - F_64(w3 ,0x34b0bcb5e19b48a8ULL) - F_64(w4 ,0x391c0cb3c5c95a63ULL) - F_64(w5 ,0x4ed8aa4ae3418acbULL) - F_64(w6 ,0x5b9cca4f7763e373ULL) - F_64(w7 ,0x682e6ff3d6b2b8a3ULL) - F_64(w8 ,0x748f82ee5defb2fcULL) - F_64(w9 ,0x78a5636f43172f60ULL) - F_64(w10,0x84c87814a1f0ab72ULL) - F_64(w11,0x8cc702081a6439ecULL) - F_64(w12,0x90befffa23631e28ULL) - F_64(w13,0xa4506cebde82bde9ULL) - F_64(w14,0xbef9a3f7b2c67915ULL) - F_64(w15,0xc67178f2e372532bULL) - - EXPAND_64 - - F_64(w0 ,0xca273eceea26619cULL) - F_64(w1 ,0xd186b8c721c0c207ULL) - F_64(w2 ,0xeada7dd6cde0eb1eULL) - F_64(w3 ,0xf57d4f7fee6ed178ULL) - F_64(w4 ,0x06f067aa72176fbaULL) - F_64(w5 ,0x0a637dc5a2c898a6ULL) - F_64(w6 ,0x113f9804bef90daeULL) - F_64(w7 ,0x1b710b35131c471bULL) - F_64(w8 ,0x28db77f523047d84ULL) - F_64(w9 ,0x32caab7b40c72493ULL) - F_64(w10,0x3c9ebe0a15c9bebcULL) - F_64(w11,0x431d67c49c100d4cULL) - F_64(w12,0x4cc5d4becb3e42b6ULL) - F_64(w13,0x597f299cfc657e2aULL) - F_64(w14,0x5fcb6fab3ad6faecULL) - F_64(w15,0x6c44198c4a475817ULL) - - a += state[0]; - b += state[1]; - c += state[2]; - d += state[3]; - e += state[4]; - f += state[5]; - g += state[6]; - h += state[7]; - - state[0] = a; - state[1] = b; - state[2] = c; - state[3] = d; - state[4] = e; - state[5] = f; - state[6] = g; - state[7] = h; - - in += 128; - inlen -= 128; - } - - store_bigendian_64(statebytes + 0,state[0]); - store_bigendian_64(statebytes + 8,state[1]); - store_bigendian_64(statebytes + 16,state[2]); - store_bigendian_64(statebytes + 24,state[3]); - store_bigendian_64(statebytes + 32,state[4]); - store_bigendian_64(statebytes + 40,state[5]); - store_bigendian_64(statebytes + 48,state[6]); - store_bigendian_64(statebytes + 56,state[7]); - - return inlen; -} - - -static const uint8_t iv_256[32] = { - 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, - 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a, - 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05, 0x68, 0x8c, - 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19 -}; - -static const uint8_t iv_512[64] = { - 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 0x67, 0xae, - 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, - 0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, - 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, - 0x2b, 0x3e, 0x6c, 0x1f, 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, - 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79 -}; - -void sha256_inc_init(uint8_t *state) { - for (size_t i = 0; i < 32; ++i) { - state[i] = iv_256[i]; - } - for (size_t i = 32; i < 40; ++i) { - state[i] = 0; - } -} - -void sha512_inc_init(uint8_t *state) { - for (size_t i = 0; i < 64; ++i) { - state[i] = iv_512[i]; - } - for (size_t i = 64; i < 72; ++i) { - state[i] = 0; - } -} - -void sha256_inc_blocks(uint8_t *state, const uint8_t *in, size_t inblocks) { - uint64_t bytes = load_bigendian_64(state + 32); - - crypto_hashblocks_sha256(state, in, 64 * inblocks); - bytes += 64 * inblocks; - - store_bigendian_64(state + 32, bytes); -} - -void sha512_inc_blocks(uint8_t *state, const uint8_t *in, size_t inblocks) { - uint64_t bytes = load_bigendian_64(state + 64); - - crypto_hashblocks_sha512(state, in, 128 * inblocks); - bytes += 128 * inblocks; - - store_bigendian_64(state + 64, bytes); -} - -void sha256_inc_finalize(uint8_t *out, uint8_t *state, const uint8_t *in, size_t inlen) { - uint8_t padded[128]; - uint64_t bytes = load_bigendian_64(state + 32) + inlen; - - crypto_hashblocks_sha256(state, in, inlen); - in += inlen; - inlen &= 63; - in -= inlen; - - for (size_t i = 0; i < inlen; ++i) { - padded[i] = in[i]; - } - padded[inlen] = 0x80; - - if (inlen < 56) { - for (size_t i = inlen + 1; i < 56; ++i) { - padded[i] = 0; - } - padded[56] = (uint8_t) (bytes >> 53); - padded[57] = (uint8_t) (bytes >> 45); - padded[58] = (uint8_t) (bytes >> 37); - padded[59] = (uint8_t) (bytes >> 29); - padded[60] = (uint8_t) (bytes >> 21); - padded[61] = (uint8_t) (bytes >> 13); - padded[62] = (uint8_t) (bytes >> 5); - padded[63] = (uint8_t) (bytes << 3); - crypto_hashblocks_sha256(state, padded, 64); - } else { - for (size_t i = inlen + 1; i < 120; ++i) { - padded[i] = 0; - } - padded[120] = (uint8_t) (bytes >> 53); - padded[121] = (uint8_t) (bytes >> 45); - padded[122] = (uint8_t) (bytes >> 37); - padded[123] = (uint8_t) (bytes >> 29); - padded[124] = (uint8_t) (bytes >> 21); - padded[125] = (uint8_t) (bytes >> 13); - padded[126] = (uint8_t) (bytes >> 5); - padded[127] = (uint8_t) (bytes << 3); - crypto_hashblocks_sha256(state, padded, 128); - } - - for (size_t i = 0; i < 32; ++i) { - out[i] = state[i]; - } - -} - -void sha512_inc_finalize(uint8_t *out, uint8_t *state, const uint8_t *in, size_t inlen) { - uint8_t padded[256]; - uint64_t bytes = load_bigendian_64(state + 64) + inlen; - - crypto_hashblocks_sha512(state, in, inlen); - in += inlen; - inlen &= 127; - in -= inlen; - - for (size_t i = 0; i < inlen; ++i) { - padded[i] = in[i]; - } - padded[inlen] = 0x80; - - if (inlen < 112) { - for (size_t i = inlen + 1; i < 119; ++i) { - padded[i] = 0; - } - padded[119] = (uint8_t) (bytes >> 61); - padded[120] = (uint8_t) (bytes >> 53); - padded[121] = (uint8_t) (bytes >> 45); - padded[122] = (uint8_t) (bytes >> 37); - padded[123] = (uint8_t) (bytes >> 29); - padded[124] = (uint8_t) (bytes >> 21); - padded[125] = (uint8_t) (bytes >> 13); - padded[126] = (uint8_t) (bytes >> 5); - padded[127] = (uint8_t) (bytes << 3); - crypto_hashblocks_sha512(state, padded, 128); - } else { - for (size_t i = inlen + 1; i < 247; ++i) { - padded[i] = 0; - } - padded[247] = (uint8_t) (bytes >> 61); - padded[248] = (uint8_t) (bytes >> 53); - padded[249] = (uint8_t) (bytes >> 45); - padded[250] = (uint8_t) (bytes >> 37); - padded[251] = (uint8_t) (bytes >> 29); - padded[252] = (uint8_t) (bytes >> 21); - padded[253] = (uint8_t) (bytes >> 13); - padded[254] = (uint8_t) (bytes >> 5); - padded[255] = (uint8_t) (bytes << 3); - crypto_hashblocks_sha512(state, padded, 256); - } - - for (size_t i = 0; i < 64; ++i) { - out[i] = state[i]; - } -} - -void sha256(uint8_t *out, const uint8_t *in, size_t inlen) { - uint8_t state[40]; - - sha256_inc_init(state); - sha256_inc_finalize(out, state, in, inlen); -} - -void sha512(uint8_t *out, const uint8_t *in, size_t inlen) { - uint8_t state[72]; - - sha512_inc_init(state); - sha512_inc_finalize(out, state, in, inlen); -} - -/** - * mgf1 function based on the SHA-256 hash function - * Note that inlen should be sufficiently small that it still allows for - * an array to be allocated on the stack. Typically 'in' is merely a seed. - * Outputs outlen number of bytes - */ -void mgf1_256(unsigned char *out, unsigned long outlen, - const unsigned char *in, unsigned long inlen) -{ - SPX_VLA(uint8_t, inbuf, inlen+4); - unsigned char outbuf[SPX_SHA256_OUTPUT_BYTES]; - unsigned long i; - - memcpy(inbuf, in, inlen); - - /* While we can fit in at least another full block of SHA256 output.. */ - for (i = 0; (i+1)*SPX_SHA256_OUTPUT_BYTES <= outlen; i++) { - u32_to_bytes(inbuf + inlen, i); - sha256(out, inbuf, inlen + 4); - out += SPX_SHA256_OUTPUT_BYTES; - } - /* Until we cannot anymore, and we fill the remainder. */ - if (outlen > i*SPX_SHA256_OUTPUT_BYTES) { - u32_to_bytes(inbuf + inlen, i); - sha256(outbuf, inbuf, inlen + 4); - memcpy(out, outbuf, outlen - i*SPX_SHA256_OUTPUT_BYTES); - } -} - -/* - * mgf1 function based on the SHA-512 hash function - */ -void mgf1_512(unsigned char *out, unsigned long outlen, - const unsigned char *in, unsigned long inlen) -{ - SPX_VLA(uint8_t, inbuf, inlen+4); - unsigned char outbuf[SPX_SHA512_OUTPUT_BYTES]; - unsigned long i; - - memcpy(inbuf, in, inlen); - - /* While we can fit in at least another full block of SHA512 output.. */ - for (i = 0; (i+1)*SPX_SHA512_OUTPUT_BYTES <= outlen; i++) { - u32_to_bytes(inbuf + inlen, i); - sha512(out, inbuf, inlen + 4); - out += SPX_SHA512_OUTPUT_BYTES; - } - /* Until we cannot anymore, and we fill the remainder. */ - if (outlen > i*SPX_SHA512_OUTPUT_BYTES) { - u32_to_bytes(inbuf + inlen, i); - sha512(outbuf, inbuf, inlen + 4); - memcpy(out, outbuf, outlen - i*SPX_SHA512_OUTPUT_BYTES); - } -} - - -/** - * Absorb the constant pub_seed using one round of the compression function - * This initializes state_seeded and state_seeded_512, which can then be - * reused in thash - **/ -void seed_state(spx_ctx *ctx) { - uint8_t block[SPX_SHA512_BLOCK_BYTES]; - size_t i; - - for (i = 0; i < SPX_N; ++i) { - block[i] = ctx->pub_seed[i]; - } - for (i = SPX_N; i < SPX_SHA512_BLOCK_BYTES; ++i) { - block[i] = 0; - } - /* block has been properly initialized for both SHA-256 and SHA-512 */ - - sha256_inc_init(ctx->state_seeded); - sha256_inc_blocks(ctx->state_seeded, block, 1); -#if SPX_SHA512 - sha512_inc_init(ctx->state_seeded_512); - sha512_inc_blocks(ctx->state_seeded_512, block, 1); -#endif -} diff --git a/Blastproof/keygen/sha2.o b/Blastproof/keygen/sha2.o deleted file mode 100644 index 089cce5..0000000 Binary files a/Blastproof/keygen/sha2.o and /dev/null differ diff --git a/Blastproof/keygen/sha3.c b/Blastproof/keygen/sha3.c deleted file mode 100644 index fb4ef05..0000000 --- a/Blastproof/keygen/sha3.c +++ /dev/null @@ -1,190 +0,0 @@ -// sha3.c -// 19-Nov-11 Markku-Juhani O. Saarinen - -// Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" -// Revised 03-Sep-15 for portability + OpenSSL - style API - -#include "sha3.h" - -// update the state with given number of rounds - -void sha3_keccakf(uint64_t st[25]) -{ - // constants - const uint64_t keccakf_rndc[24] = { - 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, - 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, - 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, - 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, - 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, - 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, - 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, - 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 - }; - const int keccakf_rotc[24] = { - 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 - }; - const int keccakf_piln[24] = { - 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 - }; - - // variables - int i, j, r; - uint64_t t, bc[5]; - -#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ - uint8_t *v; - - // endianess conversion. this is redundant on little-endian targets - for (i = 0; i < 25; i++) { - v = (uint8_t *) &st[i]; - st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) | - (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) | - (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) | - (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56); - } -#endif - - // actual iteration - for (r = 0; r < KECCAKF_ROUNDS; r++) { - - // Theta - for (i = 0; i < 5; i++) - bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; - - for (i = 0; i < 5; i++) { - t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); - for (j = 0; j < 25; j += 5) - st[j + i] ^= t; - } - - // Rho Pi - t = st[1]; - for (i = 0; i < 24; i++) { - j = keccakf_piln[i]; - bc[0] = st[j]; - st[j] = ROTL64(t, keccakf_rotc[i]); - t = bc[0]; - } - - // Chi - for (j = 0; j < 25; j += 5) { - for (i = 0; i < 5; i++) - bc[i] = st[j + i]; - for (i = 0; i < 5; i++) - st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; - } - - // Iota - st[0] ^= keccakf_rndc[r]; - } - -#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ - // endianess conversion. this is redundant on little-endian targets - for (i = 0; i < 25; i++) { - v = (uint8_t *) &st[i]; - t = st[i]; - v[0] = t & 0xFF; - v[1] = (t >> 8) & 0xFF; - v[2] = (t >> 16) & 0xFF; - v[3] = (t >> 24) & 0xFF; - v[4] = (t >> 32) & 0xFF; - v[5] = (t >> 40) & 0xFF; - v[6] = (t >> 48) & 0xFF; - v[7] = (t >> 56) & 0xFF; - } -#endif -} - -// Initialize the context for SHA3 - -int sha3_init(sha3_ctx_t *c, int mdlen) -{ - int i; - - for (i = 0; i < 25; i++) - c->st.q[i] = 0; - c->mdlen = mdlen; - c->rsiz = 200 - 2 * mdlen; - c->pt = 0; - - return 1; -} - -// update state with more data - -int sha3_update(sha3_ctx_t *c, const void *data, size_t len) -{ - size_t i; - int j; - - j = c->pt; - for (i = 0; i < len; i++) { - c->st.b[j++] ^= ((const uint8_t *) data)[i]; - if (j >= c->rsiz) { - sha3_keccakf(c->st.q); - j = 0; - } - } - c->pt = j; - - return 1; -} - -// finalize and output a hash - -int sha3_final(void *md, sha3_ctx_t *c) -{ - int i; - - c->st.b[c->pt] ^= 0x06; - c->st.b[c->rsiz - 1] ^= 0x80; - sha3_keccakf(c->st.q); - - for (i = 0; i < c->mdlen; i++) { - ((uint8_t *) md)[i] = c->st.b[i]; - } - - return 1; -} - -// compute a SHA-3 hash (md) of given byte length from "in" - -void *sha3(const void *in, size_t inlen, void *md, int mdlen) -{ - sha3_ctx_t sha3; - - sha3_init(&sha3, mdlen); - sha3_update(&sha3, in, inlen); - sha3_final(md, &sha3); - - return md; -} - -// SHAKE128 and SHAKE256 extensible-output functionality - -void shake_xof(sha3_ctx_t *c) -{ - c->st.b[c->pt] ^= 0x1F; - c->st.b[c->rsiz - 1] ^= 0x80; - sha3_keccakf(c->st.q); - c->pt = 0; -} - -void shake_out(sha3_ctx_t *c, void *out, size_t len) -{ - size_t i; - int j; - - j = c->pt; - for (i = 0; i < len; i++) { - if (j >= c->rsiz) { - sha3_keccakf(c->st.q); - j = 0; - } - ((uint8_t *) out)[i] = c->st.b[j++]; - } - c->pt = j; -} diff --git a/Blastproof/keygen/sha3.o b/Blastproof/keygen/sha3.o deleted file mode 100644 index 0fe0cf1..0000000 Binary files a/Blastproof/keygen/sha3.o and /dev/null differ diff --git a/Blastproof/keygen/sign.c b/Blastproof/keygen/sign.c deleted file mode 100644 index a8e0c3c..0000000 --- a/Blastproof/keygen/sign.c +++ /dev/null @@ -1,287 +0,0 @@ -#include -#include -#include - -#include "api.h" -#include "params.h" -#include "wots.h" -#include "fors.h" -#include "hash.h" -#include "thash.h" -#include "address.h" -#include "randombytes.h" -#include "utils.h" -#include "merkle.h" - -/* - * Returns the length of a secret key, in bytes - */ -unsigned long long crypto_sign_secretkeybytes(void) -{ - return CRYPTO_SECRETKEYBYTES; -} - -/* - * Returns the length of a public key, in bytes - */ -unsigned long long crypto_sign_publickeybytes(void) -{ - return CRYPTO_PUBLICKEYBYTES; -} - -/* - * Returns the length of a signature, in bytes - */ -unsigned long long crypto_sign_bytes(void) -{ - return CRYPTO_BYTES; -} - -/* - * Returns the length of the seed required to generate a key pair, in bytes - */ -unsigned long long crypto_sign_seedbytes(void) -{ - return CRYPTO_SEEDBYTES; -} - -/* - * Generates an SPX key pair given a seed of length - * Format sk: [SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [PUB_SEED || root] - */ -int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, - const unsigned char *seed) -{ - spx_ctx ctx; - - /* Initialize SK_SEED, SK_PRF and PUB_SEED from seed. */ - memcpy(sk, seed, CRYPTO_SEEDBYTES); - - memcpy(pk, sk + 2*SPX_N, SPX_N); - - memcpy(ctx.pub_seed, pk, SPX_N); - memcpy(ctx.sk_seed, sk, SPX_N); - - /* This hook allows the hash function instantiation to do whatever - preparation or computation it needs, based on the public seed. */ - initialize_hash_function(&ctx); - - /* Compute root node of the top-most subtree. */ - merkle_gen_root(sk + 3*SPX_N, &ctx); - - memcpy(pk + SPX_N, sk + 3*SPX_N, SPX_N); - - return 0; -} - -/* - * Generates an SPX key pair. - * Format sk: [SK_SEED || SK_PRF || PUB_SEED || root] - * Format pk: [PUB_SEED || root] - */ -int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) -{ - unsigned char seed[CRYPTO_SEEDBYTES]; - randombytes(seed, CRYPTO_SEEDBYTES); - crypto_sign_seed_keypair(pk, sk, seed); - - return 0; -} - -/** - * Returns an array containing a detached signature. - */ -int crypto_sign_signature(uint8_t *sig, size_t *siglen, - const uint8_t *m, size_t mlen, const uint8_t *sk) -{ - spx_ctx ctx; - - const unsigned char *sk_prf = sk + SPX_N; - const unsigned char *pk = sk + 2*SPX_N; - - unsigned char optrand[SPX_N]; - unsigned char mhash[SPX_FORS_MSG_BYTES]; - unsigned char root[SPX_N]; - uint32_t i; - uint64_t tree; - uint32_t idx_leaf; - uint32_t wots_addr[8] = {0}; - uint32_t tree_addr[8] = {0}; - - memcpy(ctx.sk_seed, sk, SPX_N); - memcpy(ctx.pub_seed, pk, SPX_N); - - /* This hook allows the hash function instantiation to do whatever - preparation or computation it needs, based on the public seed. */ - initialize_hash_function(&ctx); - - set_type(wots_addr, SPX_ADDR_TYPE_WOTS); - set_type(tree_addr, SPX_ADDR_TYPE_HASHTREE); - - /* Optionally, signing can be made non-deterministic using optrand. - This can help counter side-channel attacks that would benefit from - getting a large number of traces when the signer uses the same nodes. */ - randombytes(optrand, SPX_N); - /* Compute the digest randomization value. */ - gen_message_random(sig, sk_prf, optrand, m, mlen, &ctx); - - /* Derive the message digest and leaf index from R, PK and M. */ - hash_message(mhash, &tree, &idx_leaf, sig, pk, m, mlen, &ctx); - sig += SPX_N; - - set_tree_addr(wots_addr, tree); - set_keypair_addr(wots_addr, idx_leaf); - - /* Sign the message hash using FORS. */ - fors_sign(sig, root, mhash, &ctx, wots_addr); - sig += SPX_FORS_BYTES; - - for (i = 0; i < SPX_D; i++) { - set_layer_addr(tree_addr, i); - set_tree_addr(tree_addr, tree); - - copy_subtree_addr(wots_addr, tree_addr); - set_keypair_addr(wots_addr, idx_leaf); - - merkle_sign(sig, root, &ctx, wots_addr, tree_addr, idx_leaf); - sig += SPX_WOTS_BYTES + SPX_TREE_HEIGHT * SPX_N; - - /* Update the indices for the next layer. */ - idx_leaf = (tree & ((1 << SPX_TREE_HEIGHT)-1)); - tree = tree >> SPX_TREE_HEIGHT; - } - - *siglen = SPX_BYTES; - - return 0; -} - -/** - * Verifies a detached signature and message under a given public key. - */ -int crypto_sign_verify(const uint8_t *sig, size_t siglen, - const uint8_t *m, size_t mlen, const uint8_t *pk) -{ - spx_ctx ctx; - const unsigned char *pub_root = pk + SPX_N; - unsigned char mhash[SPX_FORS_MSG_BYTES]; - unsigned char wots_pk[SPX_WOTS_BYTES]; - unsigned char root[SPX_N]; - unsigned char leaf[SPX_N]; - unsigned int i; - uint64_t tree; - uint32_t idx_leaf; - uint32_t wots_addr[8] = {0}; - uint32_t tree_addr[8] = {0}; - uint32_t wots_pk_addr[8] = {0}; - - if (siglen != SPX_BYTES) { - return -1; - } - - memcpy(ctx.pub_seed, pk, SPX_N); - - /* This hook allows the hash function instantiation to do whatever - preparation or computation it needs, based on the public seed. */ - initialize_hash_function(&ctx); - - set_type(wots_addr, SPX_ADDR_TYPE_WOTS); - set_type(tree_addr, SPX_ADDR_TYPE_HASHTREE); - set_type(wots_pk_addr, SPX_ADDR_TYPE_WOTSPK); - - /* Derive the message digest and leaf index from R || PK || M. */ - /* The additional SPX_N is a result of the hash domain separator. */ - hash_message(mhash, &tree, &idx_leaf, sig, pk, m, mlen, &ctx); - sig += SPX_N; - - /* Layer correctly defaults to 0, so no need to set_layer_addr */ - set_tree_addr(wots_addr, tree); - set_keypair_addr(wots_addr, idx_leaf); - - fors_pk_from_sig(root, sig, mhash, &ctx, wots_addr); - sig += SPX_FORS_BYTES; - - /* For each subtree.. */ - for (i = 0; i < SPX_D; i++) { - set_layer_addr(tree_addr, i); - set_tree_addr(tree_addr, tree); - - copy_subtree_addr(wots_addr, tree_addr); - set_keypair_addr(wots_addr, idx_leaf); - - copy_keypair_addr(wots_pk_addr, wots_addr); - - /* The WOTS public key is only correct if the signature was correct. */ - /* Initially, root is the FORS pk, but on subsequent iterations it is - the root of the subtree below the currently processed subtree. */ - wots_pk_from_sig(wots_pk, sig, root, &ctx, wots_addr); - sig += SPX_WOTS_BYTES; - - /* Compute the leaf node using the WOTS public key. */ - thash(leaf, wots_pk, SPX_WOTS_LEN, &ctx, wots_pk_addr); - - /* Compute the root node of this subtree. */ - compute_root(root, leaf, idx_leaf, 0, sig, SPX_TREE_HEIGHT, - &ctx, tree_addr); - sig += SPX_TREE_HEIGHT * SPX_N; - - /* Update the indices for the next layer. */ - idx_leaf = (tree & ((1 << SPX_TREE_HEIGHT)-1)); - tree = tree >> SPX_TREE_HEIGHT; - } - - /* Check if the root node equals the root node in the public key. */ - if (memcmp(root, pub_root, SPX_N)) { - return -1; - } - - return 0; -} - - -/** - * Returns an array containing the signature followed by the message. - */ -int crypto_sign(unsigned char *sm, unsigned long long *smlen, - const unsigned char *m, unsigned long long mlen, - const unsigned char *sk) -{ - size_t siglen; - - crypto_sign_signature(sm, &siglen, m, (size_t)mlen, sk); - - memmove(sm + SPX_BYTES, m, mlen); - *smlen = siglen + mlen; - - return 0; -} - -/** - * Verifies a given signature-message pair under a given public key. - */ -int crypto_sign_open(unsigned char *m, unsigned long long *mlen, - const unsigned char *sm, unsigned long long smlen, - const unsigned char *pk) -{ - /* The API caller does not necessarily know what size a signature should be - but SPHINCS+ signatures are always exactly SPX_BYTES. */ - if (smlen < SPX_BYTES) { - memset(m, 0, smlen); - *mlen = 0; - return -1; - } - - *mlen = smlen - SPX_BYTES; - - if (crypto_sign_verify(sm, SPX_BYTES, sm + SPX_BYTES, (size_t)*mlen, pk)) { - memset(m, 0, smlen); - *mlen = 0; - return -1; - } - - /* If verification was successful, move the message to the right place. */ - memmove(m, sm + SPX_BYTES, *mlen); - - return 0; -} diff --git a/Blastproof/keygen/sign.o b/Blastproof/keygen/sign.o deleted file mode 100644 index b1bdbab..0000000 Binary files a/Blastproof/keygen/sign.o and /dev/null differ diff --git a/Blastproof/keygen/thash_sha2_robust.o b/Blastproof/keygen/thash_sha2_robust.o deleted file mode 100644 index e45cbc8..0000000 Binary files a/Blastproof/keygen/thash_sha2_robust.o and /dev/null differ diff --git a/Blastproof/keygen/utils.c b/Blastproof/keygen/utils.c deleted file mode 100644 index 63d52ee..0000000 --- a/Blastproof/keygen/utils.c +++ /dev/null @@ -1,154 +0,0 @@ -#include - -#include "utils.h" -#include "params.h" -#include "hash.h" -#include "thash.h" -#include "address.h" - -/** - * Converts the value of 'in' to 'outlen' bytes in big-endian byte order. - */ -void ull_to_bytes(unsigned char *out, unsigned int outlen, - unsigned long long in) -{ - int i; - - /* Iterate over out in decreasing order, for big-endianness. */ - for (i = (signed int)outlen - 1; i >= 0; i--) { - out[i] = in & 0xff; - in = in >> 8; - } -} - -void u32_to_bytes(unsigned char *out, uint32_t in) -{ - out[0] = (unsigned char)(in >> 24); - out[1] = (unsigned char)(in >> 16); - out[2] = (unsigned char)(in >> 8); - out[3] = (unsigned char)in; -} - -/** - * Converts the inlen bytes in 'in' from big-endian byte order to an integer. - */ -unsigned long long bytes_to_ull(const unsigned char *in, unsigned int inlen) -{ - unsigned long long retval = 0; - unsigned int i; - - for (i = 0; i < inlen; i++) { - retval |= ((unsigned long long)in[i]) << (8*(inlen - 1 - i)); - } - return retval; -} - -/** - * Computes a root node given a leaf and an auth path. - * Expects address to be complete other than the tree_height and tree_index. - */ -void compute_root(unsigned char *root, const unsigned char *leaf, - uint32_t leaf_idx, uint32_t idx_offset, - const unsigned char *auth_path, uint32_t tree_height, - const spx_ctx *ctx, uint32_t addr[8]) -{ - uint32_t i; - unsigned char buffer[2 * SPX_N]; - - /* If leaf_idx is odd (last bit = 1), current path element is a right child - and auth_path has to go left. Otherwise it is the other way around. */ - if (leaf_idx & 1) { - memcpy(buffer + SPX_N, leaf, SPX_N); - memcpy(buffer, auth_path, SPX_N); - } - else { - memcpy(buffer, leaf, SPX_N); - memcpy(buffer + SPX_N, auth_path, SPX_N); - } - auth_path += SPX_N; - - for (i = 0; i < tree_height - 1; i++) { - leaf_idx >>= 1; - idx_offset >>= 1; - /* Set the address of the node we're creating. */ - set_tree_height(addr, i + 1); - set_tree_index(addr, leaf_idx + idx_offset); - - /* Pick the right or left neighbor, depending on parity of the node. */ - if (leaf_idx & 1) { - thash(buffer + SPX_N, buffer, 2, ctx, addr); - memcpy(buffer, auth_path, SPX_N); - } - else { - thash(buffer, buffer, 2, ctx, addr); - memcpy(buffer + SPX_N, auth_path, SPX_N); - } - auth_path += SPX_N; - } - - /* The last iteration is exceptional; we do not copy an auth_path node. */ - leaf_idx >>= 1; - idx_offset >>= 1; - set_tree_height(addr, tree_height); - set_tree_index(addr, leaf_idx + idx_offset); - thash(root, buffer, 2, ctx, addr); -} - -/** - * For a given leaf index, computes the authentication path and the resulting - * root node using Merkle's TreeHash algorithm. - * Expects the layer and tree parts of the tree_addr to be set, as well as the - * tree type (i.e. SPX_ADDR_TYPE_HASHTREE or SPX_ADDR_TYPE_FORSTREE). - * Applies the offset idx_offset to indices before building addresses, so that - * it is possible to continue counting indices across trees. - */ -void treehash(unsigned char *root, unsigned char *auth_path, const spx_ctx* ctx, - uint32_t leaf_idx, uint32_t idx_offset, uint32_t tree_height, - void (*gen_leaf)( - unsigned char* /* leaf */, - const spx_ctx* /* ctx */, - uint32_t /* addr_idx */, const uint32_t[8] /* tree_addr */), - uint32_t tree_addr[8]) -{ - SPX_VLA(uint8_t, stack, (tree_height+1)*SPX_N); - SPX_VLA(unsigned int, heights, tree_height+1); - unsigned int offset = 0; - uint32_t idx; - uint32_t tree_idx; - - for (idx = 0; idx < (uint32_t)(1 << tree_height); idx++) { - /* Add the next leaf node to the stack. */ - gen_leaf(stack + offset*SPX_N, ctx, idx + idx_offset, tree_addr); - offset++; - heights[offset - 1] = 0; - - /* If this is a node we need for the auth path.. */ - if ((leaf_idx ^ 0x1) == idx) { - memcpy(auth_path, stack + (offset - 1)*SPX_N, SPX_N); - } - - /* While the top-most nodes are of equal height.. */ - while (offset >= 2 && heights[offset - 1] == heights[offset - 2]) { - /* Compute index of the new node, in the next layer. */ - tree_idx = (idx >> (heights[offset - 1] + 1)); - - /* Set the address of the node we're creating. */ - set_tree_height(tree_addr, heights[offset - 1] + 1); - set_tree_index(tree_addr, - tree_idx + (idx_offset >> (heights[offset-1] + 1))); - /* Hash the top-most nodes from the stack together. */ - thash(stack + (offset - 2)*SPX_N, - stack + (offset - 2)*SPX_N, 2, ctx, tree_addr); - offset--; - /* Note that the top-most node is now one layer higher. */ - heights[offset - 1]++; - - /* If this is a node we need for the auth path.. */ - if (((leaf_idx >> heights[offset - 1]) ^ 0x1) == tree_idx) { - memcpy(auth_path + heights[offset - 1]*SPX_N, - stack + (offset - 1)*SPX_N, SPX_N); - } - } - } - memcpy(root, stack, SPX_N); -} diff --git a/Blastproof/keygen/utils.o b/Blastproof/keygen/utils.o deleted file mode 100644 index b13ec2f..0000000 Binary files a/Blastproof/keygen/utils.o and /dev/null differ diff --git a/Blastproof/keygen/utilsx1.c b/Blastproof/keygen/utilsx1.c deleted file mode 100644 index f6a6700..0000000 --- a/Blastproof/keygen/utilsx1.c +++ /dev/null @@ -1,100 +0,0 @@ -#include - -#include "utils.h" -#include "utilsx1.h" -#include "params.h" -#include "thash.h" -#include "address.h" - -/* - * Generate the entire Merkle tree, computing the authentication path for - * leaf_idx, and the resulting root node using Merkle's TreeHash algorithm. - * Expects the layer and tree parts of the tree_addr to be set, as well as the - * tree type (i.e. SPX_ADDR_TYPE_HASHTREE or SPX_ADDR_TYPE_FORSTREE) - * - * This expects tree_addr to be initialized to the addr structures for the - * Merkle tree nodes - * - * Applies the offset idx_offset to indices before building addresses, so that - * it is possible to continue counting indices across trees. - * - * This works by using the standard Merkle tree building algorithm, - */ -void treehashx1(unsigned char *root, unsigned char *auth_path, - const spx_ctx* ctx, - uint32_t leaf_idx, uint32_t idx_offset, - uint32_t tree_height, - void (*gen_leaf)( - unsigned char* /* Where to write the leaves */, - const spx_ctx* /* ctx */, - uint32_t idx, void *info), - uint32_t tree_addr[8], - void *info) -{ - /* This is where we keep the intermediate nodes */ - SPX_VLA(uint8_t, stack, tree_height*SPX_N); - - uint32_t idx; - uint32_t max_idx = (uint32_t)((1 << tree_height) - 1); - for (idx = 0;; idx++) { - unsigned char current[2*SPX_N]; /* Current logical node is at */ - /* index[SPX_N]. We do this to minimize the number of copies */ - /* needed during a thash */ - gen_leaf( ¤t[SPX_N], ctx, idx + idx_offset, - info ); - - /* Now combine the freshly generated right node with previously */ - /* generated left ones */ - uint32_t internal_idx_offset = idx_offset; - uint32_t internal_idx = idx; - uint32_t internal_leaf = leaf_idx; - uint32_t h; /* The height we are in the Merkle tree */ - for (h=0;; h++, internal_idx >>= 1, internal_leaf >>= 1) { - - /* Check if we hit the top of the tree */ - if (h == tree_height) { - /* We hit the root; return it */ - memcpy( root, ¤t[SPX_N], SPX_N ); - return; - } - - /* - * Check if the node we have is a part of the - * authentication path; if it is, write it out - */ - if ((internal_idx ^ internal_leaf) == 0x01) { - memcpy( &auth_path[ h * SPX_N ], - ¤t[SPX_N], - SPX_N ); - } - - /* - * Check if we're at a left child; if so, stop going up the stack - * Exception: if we've reached the end of the tree, keep on going - * (so we combine the last 4 nodes into the one root node in two - * more iterations) - */ - if ((internal_idx & 1) == 0 && idx < max_idx) { - break; - } - - /* Ok, we're at a right node */ - /* Now combine the left and right logical nodes together */ - - /* Set the address of the node we're creating. */ - internal_idx_offset >>= 1; - set_tree_height(tree_addr, h + 1); - set_tree_index(tree_addr, internal_idx/2 + internal_idx_offset ); - - unsigned char *left = &stack[h * SPX_N]; - memcpy( ¤t[0], left, SPX_N ); - thash( ¤t[1 * SPX_N], - ¤t[0 * SPX_N], - 2, ctx, tree_addr); - } - - /* We've hit a left child; save the current for when we get the */ - /* corresponding right right */ - memcpy( &stack[h * SPX_N], ¤t[SPX_N], SPX_N); - } -} diff --git a/Blastproof/keygen/utilsx1.o b/Blastproof/keygen/utilsx1.o deleted file mode 100644 index 56b5e0d..0000000 Binary files a/Blastproof/keygen/utilsx1.o and /dev/null differ diff --git a/Blastproof/keygen/wots.c b/Blastproof/keygen/wots.c deleted file mode 100644 index df83278..0000000 --- a/Blastproof/keygen/wots.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include - -#include "utils.h" -#include "utilsx1.h" -#include "hash.h" -#include "thash.h" -#include "wots.h" -#include "wotsx1.h" -#include "address.h" -#include "params.h" - -// TODO clarify address expectations, and make them more uniform. -// TODO i.e. do we expect types to be set already? -// TODO and do we expect modifications or copies? - -/** - * Computes the chaining function. - * out and in have to be n-byte arrays. - * - * Interprets in as start-th value of the chain. - * addr has to contain the address of the chain. - */ -static void gen_chain(unsigned char *out, const unsigned char *in, - unsigned int start, unsigned int steps, - const spx_ctx *ctx, uint32_t addr[8]) -{ - uint32_t i; - - /* Initialize out with the value at position 'start'. */ - memcpy(out, in, SPX_N); - - /* Iterate 'steps' calls to the hash function. */ - for (i = start; i < (start+steps) && i < SPX_WOTS_W; i++) { - set_hash_addr(addr, i); - thash(out, out, 1, ctx, addr); - } -} - -/** - * base_w algorithm as described in draft. - * Interprets an array of bytes as integers in base w. - * This only works when log_w is a divisor of 8. - */ -static void base_w(unsigned int *output, const int out_len, - const unsigned char *input) -{ - int in = 0; - int out = 0; - unsigned char total; - int bits = 0; - int consumed; - - for (consumed = 0; consumed < out_len; consumed++) { - if (bits == 0) { - total = input[in]; - in++; - bits += 8; - } - bits -= SPX_WOTS_LOGW; - output[out] = (total >> bits) & (SPX_WOTS_W - 1); - out++; - } -} - -/* Computes the WOTS+ checksum over a message (in base_w). */ -static void wots_checksum(unsigned int *csum_base_w, - const unsigned int *msg_base_w) -{ - unsigned int csum = 0; - unsigned char csum_bytes[(SPX_WOTS_LEN2 * SPX_WOTS_LOGW + 7) / 8]; - unsigned int i; - - /* Compute checksum. */ - for (i = 0; i < SPX_WOTS_LEN1; i++) { - csum += SPX_WOTS_W - 1 - msg_base_w[i]; - } - - /* Convert checksum to base_w. */ - /* Make sure expected empty zero bits are the least significant bits. */ - csum = csum << ((8 - ((SPX_WOTS_LEN2 * SPX_WOTS_LOGW) % 8)) % 8); - ull_to_bytes(csum_bytes, sizeof(csum_bytes), csum); - base_w(csum_base_w, SPX_WOTS_LEN2, csum_bytes); -} - -/* Takes a message and derives the matching chain lengths. */ -void chain_lengths(unsigned int *lengths, const unsigned char *msg) -{ - base_w(lengths, SPX_WOTS_LEN1, msg); - wots_checksum(lengths + SPX_WOTS_LEN1, lengths); -} - -/** - * Takes a WOTS signature and an n-byte message, computes a WOTS public key. - * - * Writes the computed public key to 'pk'. - */ -void wots_pk_from_sig(unsigned char *pk, - const unsigned char *sig, const unsigned char *msg, - const spx_ctx *ctx, uint32_t addr[8]) -{ - unsigned int lengths[SPX_WOTS_LEN]; - uint32_t i; - - chain_lengths(lengths, msg); - - for (i = 0; i < SPX_WOTS_LEN; i++) { - set_chain_addr(addr, i); - gen_chain(pk + i*SPX_N, sig + i*SPX_N, - lengths[i], SPX_WOTS_W - 1 - lengths[i], ctx, addr); - } -} diff --git a/Blastproof/keygen/wots.o b/Blastproof/keygen/wots.o deleted file mode 100644 index 35ada9f..0000000 Binary files a/Blastproof/keygen/wots.o and /dev/null differ diff --git a/Blastproof/keygen/wotsx1.c b/Blastproof/keygen/wotsx1.c deleted file mode 100644 index dfb3780..0000000 --- a/Blastproof/keygen/wotsx1.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include - -#include "utils.h" -#include "hash.h" -#include "thash.h" -#include "wots.h" -#include "wotsx1.h" -#include "address.h" -#include "params.h" - -/* - * This generates a WOTS public key - * It also generates the WOTS signature if leaf_info indicates - * that we're signing with this WOTS key - */ -void wots_gen_leafx1(unsigned char *dest, - const spx_ctx *ctx, - uint32_t leaf_idx, void *v_info) { - struct leaf_info_x1 *info = v_info; - uint32_t *leaf_addr = info->leaf_addr; - uint32_t *pk_addr = info->pk_addr; - unsigned int i, k; - unsigned char pk_buffer[ SPX_WOTS_BYTES ]; - unsigned char *buffer; - uint32_t wots_k_mask; - - if (leaf_idx == info->wots_sign_leaf) { - /* We're traversing the leaf that's signing; generate the WOTS */ - /* signature */ - wots_k_mask = 0; - } else { - /* Nope, we're just generating pk's; turn off the signature logic */ - wots_k_mask = (uint32_t)~0; - } - - set_keypair_addr( leaf_addr, leaf_idx ); - set_keypair_addr( pk_addr, leaf_idx ); - - for (i = 0, buffer = pk_buffer; i < SPX_WOTS_LEN; i++, buffer += SPX_N) { - uint32_t wots_k = info->wots_steps[i] | wots_k_mask; /* Set wots_k to */ - /* the step if we're generating a signature, ~0 if we're not */ - - /* Start with the secret seed */ - set_chain_addr(leaf_addr, i); - set_hash_addr(leaf_addr, 0); - set_type(leaf_addr, SPX_ADDR_TYPE_WOTSPRF); - - prf_addr(buffer, ctx, leaf_addr); - - set_type(leaf_addr, SPX_ADDR_TYPE_WOTS); - - /* Iterate down the WOTS chain */ - for (k=0;; k++) { - /* Check if this is the value that needs to be saved as a */ - /* part of the WOTS signature */ - if (k == wots_k) { - memcpy( info->wots_sig + i * SPX_N, buffer, SPX_N ); - } - - /* Check if we hit the top of the chain */ - if (k == SPX_WOTS_W - 1) break; - - /* Iterate one step on the chain */ - set_hash_addr(leaf_addr, k); - - thash(buffer, buffer, 1, ctx, leaf_addr); - } - } - - /* Do the final thash to generate the public keys */ - thash(dest, pk_buffer, SPX_WOTS_LEN, ctx, pk_addr); -} diff --git a/Blastproof/keygen/wotsx1.o b/Blastproof/keygen/wotsx1.o deleted file mode 100644 index f577190..0000000 Binary files a/Blastproof/keygen/wotsx1.o and /dev/null differ diff --git a/Blastproof/ovmf.sh b/Blastproof/ovmf.sh new file mode 100755 index 0000000..af6a077 --- /dev/null +++ b/Blastproof/ovmf.sh @@ -0,0 +1,10 @@ +. ./edksetup.sh +status=$? +if [[ $status -eq 0 ]]; then + echo " done." +else + echo -e "\nError:\n$(cat "$tmpfile")" + exit $status +fi +rm -f "$tmpfile" +build -p OvmfPkg/OvmfPkgX64.dsc -b RELEASE -a X64 -t GCC diff --git a/Blastproof/src/keycard.json b/Blastproof/src/keycard.json new file mode 100644 index 0000000..1ddef0c --- /dev/null +++ b/Blastproof/src/keycard.json @@ -0,0 +1,41 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Keycard build", + "actions":[ + { + "action":"compile_one_asm", + "args":{ + "source_variables":false, + "source":"keycard.asm", + "assembler_variables":true, + "assembler":"$ASSEMBLER$", + "pre_arguments_variables":true, + "pre_arguments":[ + "-f $ASM_OUTPUT_FORMAT$" + ], + "post_arguments_variables":true, + "post_arguments":[ + "-o $KEYCARD_BINARY_NAME$" + ], + "output_file_variables":true, + "output_file":"$KEYCARD_BINARY_NAME$", + "success_status":[ + 0 + ], + "ignore_success_status":true, + "cache_authorized":true + } + }, + { + "action":"move_file", + "args":{ + "source_file_variables":true, + "source_file":"$KEYCARD_BINARY_NAME$", + "destination_folder_variables":true, + "destination_folder":"%rootcallerfolder%/$INITFS_DIR$" + } + } + ] +} diff --git a/Blastproof/src/libs/include/conf.h b/Blastproof/src/libs/include/conf.h index f57eb0e..5694cbd 100644 --- a/Blastproof/src/libs/include/conf.h +++ b/Blastproof/src/libs/include/conf.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_CONF_H #define BP_LIB_CONF_H #include @@ -38,6 +39,7 @@ typedef struct { BOOLEAN kernel_log_disable_serial_port; BOOLEAN kernel_disable_serial_port; UINT16 kernel_log_ring_size; + UINT16 kernel_kbd_events_queue_capacity; } bp_conf_BOOT_CONF; STATIC CONST CHAR16 *CONST bp_conf_boot_conf_params[]={ L"serial_port_enabled", @@ -56,7 +58,8 @@ STATIC CONST CHAR16 *CONST bp_conf_boot_conf_params[]={ L"kernel_bench_iterations", L"kernel_log_disable_serial_port", L"kernel_disable_serial_port", - L"kernel_log_ring_size" + L"kernel_log_ring_size", + L"kernel_kbd_events_queue_capacity" }; #define BP_CONF_BOOT_CONF_PARAMS_SIZE (sizeof(bp_conf_boot_conf_params)/sizeof(bp_conf_boot_conf_params[0])) EFI_STATUS bp_conf_get_lines_number(bp_disk_FILE *file,UINTN *line_number); diff --git a/Blastproof/src/libs/include/console.h b/Blastproof/src/libs/include/console.h index f93ba92..0dc8e42 100644 --- a/Blastproof/src/libs/include/console.h +++ b/Blastproof/src/libs/include/console.h @@ -1,13 +1,18 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_CONSOLE_H #define BP_LIB_CONSOLE_H #include #include "Uefi/UefiBaseType.h" #include "disk.h" -#include "font.h" +#define BP_CONSOLE_DEFAULT_LAYOUT_INDEX 1 typedef struct { CHAR16* password; UINTN size; } bp_console_PASSWORD; +VOID bp_console_clear_screen(); +VOID bp_console_set_console_mode(); +EFI_STATUS bp_console_clear_row(UINTN row); +EFI_STATUS bp_console_write_centered(CHAR16 *text,UINTN row); VOID bp_console_print_file(bp_disk_FILE *file); -EFI_STATUS bp_console_read_password(CHAR16 *prompt,bp_console_PASSWORD **pwd,CHAR16 hiding_char); +EFI_STATUS bp_console_read_password(CHAR16 *prompt,bp_console_PASSWORD **pwd); #endif diff --git a/Blastproof/src/libs/include/cpu.h b/Blastproof/src/libs/include/cpu.h deleted file mode 100644 index b660835..0000000 --- a/Blastproof/src/libs/include/cpu.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef BP_LIB_CPU_H -#define BP_LIB_CPU_H -#include -typedef struct { - CHAR8 vendor[13]; - UINT32 max_cpuid_level; - UINT32 stepping; - UINT32 model; - UINT32 family; - UINT32 ext_model; - UINT32 ext_family; - UINT32 display_family; - UINT32 display_model; - CHAR16 ecx_bin[33]; - CHAR16 edx_bin[33]; -} bp_cpu_CPU_INFO; -EFI_STATUS bp_cpu_fill_cpu_info(bp_cpu_CPU_INFO* cpu_info); -#endif diff --git a/Blastproof/src/libs/include/crypto.h b/Blastproof/src/libs/include/crypto.h index 077d9d4..f5f5956 100644 --- a/Blastproof/src/libs/include/crypto.h +++ b/Blastproof/src/libs/include/crypto.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_CRYPTO_H #define BP_LIB_CRYPTO_H #include diff --git a/Blastproof/src/libs/include/debug.h b/Blastproof/src/libs/include/debug.h index 4b7da5c..9435ded 100644 --- a/Blastproof/src/libs/include/debug.h +++ b/Blastproof/src/libs/include/debug.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_DEBUG_H #define BP_LIB_DEBUG_H #include diff --git a/Blastproof/src/libs/include/default.h b/Blastproof/src/libs/include/default.h index ab67642..10b5ee7 100644 --- a/Blastproof/src/libs/include/default.h +++ b/Blastproof/src/libs/include/default.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_DEFAULT_H #define BP_LIB_DEFAULT_H #include @@ -17,4 +18,5 @@ #define BP_DEFAULT_CONF_KERNEL_LOG_DISABLE_SERIAL_PORT TRUE #define BP_DEFAULT_CONF_KERNEL_DISABLE_SERIAL_PORT FALSE #define BP_DEFAULT_CONF_KERNEL_LOG_RING_SIZE 2048 +#define BP_DEFAULT_CONF_KERNEL_KBD_EVENTS_QUEUE_CAPACITY 256 #endif diff --git a/Blastproof/src/libs/include/disk.h b/Blastproof/src/libs/include/disk.h index 0fe4735..421fc8e 100644 --- a/Blastproof/src/libs/include/disk.h +++ b/Blastproof/src/libs/include/disk.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_DISK_H #define BP_LIB_DISK_H #include diff --git a/Blastproof/src/libs/include/font.h b/Blastproof/src/libs/include/font.h index c39e2a9..6746f91 100644 --- a/Blastproof/src/libs/include/font.h +++ b/Blastproof/src/libs/include/font.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_FONT_H #define BP_LIB_FONT_H #include diff --git a/Blastproof/src/libs/include/graphic.h b/Blastproof/src/libs/include/graphic.h index 99bdc75..44d1bce 100644 --- a/Blastproof/src/libs/include/graphic.h +++ b/Blastproof/src/libs/include/graphic.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_GRAPHIC_H #define BP_LIB_GRAPHIC_H #include diff --git a/Blastproof/src/libs/include/initfs.h b/Blastproof/src/libs/include/initfs.h index ba88b8d..c7fcc3d 100644 --- a/Blastproof/src/libs/include/initfs.h +++ b/Blastproof/src/libs/include/initfs.h @@ -1,9 +1,11 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_INITFS_H #define BP_LIB_INITFS_H #include #include #include "../include/disk.h" -#define BP_INITFS_INITFS_SUPPORTED_VERSION 0x0001 +#include "common/versions.h" +#define BP_INITFS_INITFS_SUPPORTED_VERSION VY_COMMON_VERSIONS_INITFS #pragma pack(1) typedef struct { UINT8 sig[8]; diff --git a/Blastproof/src/libs/include/layout.h b/Blastproof/src/libs/include/layout.h new file mode 100644 index 0000000..24cf64b --- /dev/null +++ b/Blastproof/src/libs/include/layout.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef BP_LIB_LAYOUT_H +#define BP_LIB_LAYOUT_H +#include +typedef struct { + CHAR16 char_source; + CHAR16 char_dest; +} bp_layout_CHAR_CONV; +typedef struct { + UINTN conv_count; + bp_layout_CHAR_CONV conv_table[]; +} bp_layout_CONV_TABLE; +CHAR16 **bp_layout_get_layout_list(); +UINTN bp_layout_get_layout_count(); +CHAR16 bp_layout_convert_char(CHAR16 source,UINTN layout_index); +#endif diff --git a/Blastproof/src/libs/include/layouts/azerty.h b/Blastproof/src/libs/include/layouts/azerty.h new file mode 100644 index 0000000..cbff43b --- /dev/null +++ b/Blastproof/src/libs/include/layouts/azerty.h @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef BP_LIB_LAYOUT_AZERTY_H +#define BP_LIB_LAYOUT_AZERTY_H +#include "../layout.h" +bp_layout_CONV_TABLE azerty_convs={ + .conv_count=49, + .conv_table={ + {L'a',L'q'}, + {L'A',L'Q'}, + {L'z',L'w'}, + {L'Z',L'W'}, + {L'q',L'a'}, + {L'Q',L'A'}, + {L'm',L','}, + {L'M',L'?'}, + {L'w',L'z'}, + {L'W',L'Z'}, + {L';',L'm'}, + {L':',L'M'}, + {L',',L';'}, + {L'<',L'.'}, + {L'.',L':'}, + {L'>',L'/'}, + {L'/',L'!'}, + {L'?',L'§'}, + {L'\'',L' '}, + {L'"',L'%'}, + {L'\\',L'*'}, + {L'|',L'µ'}, + {L'[',L'^'}, + {L'{',L' '}, + {L']',L'$'}, + {L'}',L' '}, + {L'-',L')'}, + {L'_',L' '}, + {L'`',L'²'}, + {L'1',L'&'}, + {L'!',L'1'}, + {L'2',L' '}, + {L'@',L'2'}, + {L'3',L'\"'}, + {L'#',L'3'}, + {L'4',L'\''}, + {L'$',L'4'}, + {L'5',L'('}, + {L'%',L'5'}, + {L'6',L'-'}, + {L'^',L'6'}, + {L'7',L' '}, + {L'&',L'7'}, + {L'8',L'_'}, + {L'*',L'8'}, + {L'9',L' '}, + {L'(',L'9'}, + {L'0',L' '}, + {L')',L'0'} + } +}; +#endif diff --git a/Blastproof/src/libs/include/layouts/layout_registry.h b/Blastproof/src/libs/include/layouts/layout_registry.h new file mode 100644 index 0000000..1aa3ac1 --- /dev/null +++ b/Blastproof/src/libs/include/layouts/layout_registry.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef BP_LIB_LAYOUT_REGISTRY_H +#define BP_LIB_LAYOUT_REGISTRY_H +#include +// Add the #include of your layout here +#include "qwerty.h" +#include "azerty.h" +// Add the name of youy layout here +CHAR16 *layout_list[2]={ + L"qwerty",L"azerty" +}; +UINTN layout_count=sizeof(layout_list)/sizeof(layout_list[0]); +// Add your layout conversion layout here +bp_layout_CONV_TABLE *layout_conversions_table[]={ + &qwerty_convs,&azerty_convs +}; +#endif diff --git a/Blastproof/src/libs/include/layouts/qwerty.h b/Blastproof/src/libs/include/layouts/qwerty.h new file mode 100644 index 0000000..bf66233 --- /dev/null +++ b/Blastproof/src/libs/include/layouts/qwerty.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef BP_LIB_LAYOUT_QWERTY_H +#define BP_LIB_LAYOUT_QWERTY_H +#include "../layout.h" +bp_layout_CONV_TABLE qwerty_convs={ + .conv_count=0, + .conv_table={ + } +}; +#endif diff --git a/Blastproof/src/libs/include/ui.h b/Blastproof/src/libs/include/ui.h index 6669824..07f5d66 100644 --- a/Blastproof/src/libs/include/ui.h +++ b/Blastproof/src/libs/include/ui.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_UI_H #define BP_LIB_UI_H #include diff --git a/Blastproof/src/libs/include/vftm.h b/Blastproof/src/libs/include/vftm.h new file mode 100644 index 0000000..c7a4266 --- /dev/null +++ b/Blastproof/src/libs/include/vftm.h @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef BP_LIB_VFTM_H +#define BP_LIB_VFTM_H +#include +#include +#include "common/versions.h" +#define BP_VFTM_SIGNATURE {'V','y','F','a','t','S','i','g'} +#define BP_VFTM_SUPPORTED_MANIFEST_VERSION VY_COMMON_VERSIONS_MANIFEST +#define BP_VFTM_SUPPORTED_OS_VERSION VY_COMMON_VERSIONS_OS +#define BP_VFTM_SUPPORTED_BOOTLOADER_VERSION VY_COMMON_VERSIONS_BOOTLOADER +#pragma pack(1) +typedef struct { + UINT8 sig[8]; + UINT16 manifest_version; + UINT16 bootloader_version; + UINT32 os_version; + UINT8 fat_hash[64]; + UINT8 fat_build_id[32]; + UINT64 clusters_count; + UINT64 bytes_per_sector; + UINT64 sectors_per_cluster; + UINT64 fat_size_bytes; + UINT64 fat_offset_bytes; + UINT64 bootloader_cluster_count; + UINT64 bootloader_cluster_offset; + UINT64 bootloader_build_id; + UINT8 fat_header_hash[64]; + UINT8 bootloader_binary_hash[64]; + UINT64 signature_offset_bytes; + UINT64 signature_size; + UINT8 gpt_disk_guid[16]; + UINT8 gpt_efi_part_unique_guid[16]; + UINT8 manifest_hash[64]; +} bp_vftm_MANIFEST; +#pragma pack() +typedef struct { + UINT8 disk_guid[16]; + UINT8 efi_part_unique_guid[16]; + bp_vftm_MANIFEST manifest; + UINT8 pk_manifest[64]; + UINT8 *manifest_signature; + EFI_BLOCK_IO_PROTOCOL *block_io_esp; + EFI_BLOCK_IO_PROTOCOL *block_io_disk; + UINT8 *partition_table_buffer; + UINTN part_count; +} bp_vftm_VFTM_ASSETS; +#pragma pack(1) +typedef struct { + UINT8 BS_JmpBoot[3]; + UINT8 BS_OEMName[8]; + UINT16 BPB_BytsPerSec; + UINT8 BPB_SecPerClus; + UINT16 BPB_RsvdSecCnt; + UINT8 BPB_NumFATs; + UINT16 BPB_RootEntCnt; + UINT16 BPB_TotSec16; + UINT8 BPB_Media; + UINT16 BPB_FATSz16; + UINT16 BPB_SecPerTrk; + UINT16 BPB_NumHeads; + UINT32 BPB_HiddSec; + UINT32 BPB_TotSec32; + UINT32 BPB_FATSz32; + UINT16 BPB_ExtFlags; + UINT16 BPB_FSVer; + UINT32 BPB_RootClus; + UINT16 BPB_FSInfo; + UINT16 BPB_BkBootSec; + UINT8 BPB_Reserved[12]; + UINT8 BS_DrvNum; + UINT8 BS_Reserved; + UINT8 BS_BootSig; + UINT32 BS_VolID; + UINT8 BS_VolLab[11]; + UINT8 BS_FilSysType[8]; + UINT8 BS_BootCode32[420]; + UINT16 BS_Sign; +} bp_vftm_FAT32_HEADER; +#pragma pack() +EFI_STATUS bp_vftm_get_vftm_assets(EFI_HANDLE image_handle); +EFI_STATUS bp_vftm_check_manifest_authenticity(UINT8 *pk_root,UINT8* sig_root); +EFI_STATUS bp_vftm_check_manifest_content(); +bp_vftm_VFTM_ASSETS *bp_vftm_get_assets(); +#endif diff --git a/Blastproof/src/libs/include/vyx.h b/Blastproof/src/libs/include/vyx.h index bffe617..d00a4b9 100644 --- a/Blastproof/src/libs/include/vyx.h +++ b/Blastproof/src/libs/include/vyx.h @@ -1,13 +1,17 @@ +// SPDX-License-Identifier: MPL-2.0 #ifndef BP_LIB_VYX_H #define BP_LIB_VYX_H #include #include "disk.h" -#define BP_VYX_SUPPORTED_VERSION 0x0001 +#include "common/versions.h" +#define BP_VYX_SUPPORTED_VERSION VY_COMMON_VERSIONS_VYX #define BP_VYX_SHELTER_BOOT_CONFIG_VA 0x00180000 #define BP_VYX_SHELTER_MEMORY_MAP_PAGES_COUNT 16 #define BP_VYX_SHELTER_MEMORY_MAP_VA 0x00190000 #define BP_VYX_SHELTER_PT_PAGE_COUNT 4096 #define BP_VYX_SHELTER_LOGGING_RING_BUFFER_VA 0xFFFFFFFFF0000000ULL +#define BP_VYX_PAYLOAD_EXECUTABLE (1<<0) +#define BP_VYX_PAYLOAD_WRITABLE (1<<1) #pragma pack(1) typedef struct { UINT8 sig[3]; @@ -18,8 +22,18 @@ typedef struct { UINT64 data_size_padded; UINT64 rodata_size_padded; UINT64 bss_size_padded; + UINT64 payload_count; } bp_vyx_VYX_HEADER; #pragma pack() +#pragma pack(1) +typedef struct { + UINT8 sig[8]; + UINT32 payload_size_bytes; + UINT32 payload_pages_count; + UINT8 map_flags; + UINT64 load_address; +} bp_vyx_PAYLOAD_HEADER; +#pragma pack() typedef struct { EFI_PHYSICAL_ADDRESS text_addr_phys; EFI_PHYSICAL_ADDRESS data_addr_phys; @@ -34,7 +48,25 @@ typedef struct { EFI_PHYSICAL_ADDRESS shelter_logging_ring_buffer_addr_phys; UINTN shelter_logging_ring_buffer_pages_count; UINTN keycard_page_count; + UINT64 payload_count; + UINT32 *payloads_page_count_array; + UINT8 *payloads_map_flags_array; + EFI_PHYSICAL_ADDRESS *payloads_addr_phys_array; + EFI_VIRTUAL_ADDRESS *payloads_addr_virt_array; } bp_vyx_LOADER_SETTING; +typedef struct __attribute__((aligned(8))) { + BOOLEAN fb_present; + EFI_VIRTUAL_ADDRESS fb_pa; + UINT32 white_pixel_value; + UINT32 gray_pixel_value; + UINT64 size_in_bytes; + UINT32 fb_height; + UINT32 fb_width; + UINT16 text_x; + UINT16 text_y; + UINT16 text_width; + UINT16 text_height; +} bp_vyx_SHELTER_FB_CONFIG; typedef struct __attribute__((aligned(8))) { UINT8 sig_start[8]; UINT8 log_level; @@ -46,6 +78,10 @@ typedef struct __attribute__((aligned(8))) { BOOLEAN log_disable_serial_port; BOOLEAN disable_serial_port; UINT16 log_ring_size; + UINT64 acpi_rsdp; + UINT8 acpi_ver; + UINT16 kbd_events_queue_capacity; + bp_vyx_SHELTER_FB_CONFIG fb_config; UINT8 sig_end[8]; } bp_vyx_SHELTER_BOOT_CONFIG; #pragma pack(1) @@ -65,7 +101,7 @@ typedef struct { } bp_vyx_SHELTER_MEMORY_MAP_HEADER; #pragma pack() EFI_STATUS bp_vyx_get_header(bp_disk_FILE *file,bp_vyx_VYX_HEADER **header); -EFI_STATUS bp_vyx_create_shelter_boot_conf(UINT8 log_level,BOOLEAN test_benchmark,UINT64 bench_iterations,BOOLEAN log_disable_serial_port,BOOLEAN disable_serial_port,UINT16 log_ring_size,bp_vyx_SHELTER_BOOT_CONFIG *boot_config); +EFI_STATUS bp_vyx_create_shelter_boot_conf(UINT8 log_level,BOOLEAN test_benchmark,UINT64 bench_iterations,BOOLEAN log_disable_serial_port,BOOLEAN disable_serial_port,UINT16 log_ring_size,UINT64 acpi_rsdp,UINT8 acpi_ver,UINT16 kbd_events_queue_capacity,bp_vyx_SHELTER_BOOT_CONFIG *boot_config); EFI_STATUS bp_vyx_init_pt_pool_allocator(); UINT64 bp_vyx_get_pt_pool_allocator(); EFI_PHYSICAL_ADDRESS bp_vyx_pt_pool_alloc_one_page(EFI_PHYSICAL_ADDRESS pt_pool_base); diff --git a/Blastproof/src/libs/src/conf.c b/Blastproof/src/libs/src/conf.c index 0612548..32ca40b 100644 --- a/Blastproof/src/libs/src/conf.c +++ b/Blastproof/src/libs/src/conf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/conf.h" #include "../include/default.h" #include @@ -154,6 +155,7 @@ EFI_STATUS bp_conf_fill_default_boot_conf(bp_conf_BOOT_CONF **boot_conf) { (*boot_conf)->kernel_log_disable_serial_port=BP_DEFAULT_CONF_KERNEL_LOG_DISABLE_SERIAL_PORT; (*boot_conf)->kernel_disable_serial_port=BP_DEFAULT_CONF_KERNEL_DISABLE_SERIAL_PORT; (*boot_conf)->kernel_log_ring_size=BP_DEFAULT_CONF_KERNEL_LOG_RING_SIZE; + (*boot_conf)->kernel_kbd_events_queue_capacity=BP_DEFAULT_CONF_KERNEL_KBD_EVENTS_QUEUE_CAPACITY; return status; } EFI_STATUS bp_conf_fill_boot_conf(bp_conf_CONF *conf,bp_conf_BOOT_CONF **boot_conf) { @@ -426,6 +428,33 @@ EFI_STATUS bp_conf_fill_boot_conf(bp_conf_CONF *conf,bp_conf_BOOT_CONF **boot_co } (*boot_conf)->kernel_log_ring_size=vert; } + } else if (StrCmp(conf->pairs[i].key,L"kernel_kbd_events_queue_capacity")==0) { + if (StrCmp(conf->pairs[i].value,L"0")==0) { + Print(L"[BlastConf] Error for key 'kernel_kbd_events_queue_capacity': %s shouldn't be below 64.\n",conf->pairs[i].value); + return EFI_INVALID_PARAMETER; + } else { + UINT64 cap=0; + if (conf->pairs[i].value==NULL) { + continue; + } + for (UINTN j=0;conf->pairs[i].value[j]!=0;j++) { + CHAR16 c=conf->pairs[i].value[j]; + if (c>=L'0' && c<=L'9') { + cap=cap*10+(c-L'0'); + } else { + Print(L"[BlastConf] Error for key 'kernel_kbd_events_queue_capacity': %s isn't a valid integer value.\n",conf->pairs[i].value); + return EFI_INVALID_PARAMETER; + } + } + if (cap>65535) { + Print(L"[BlastConf] Error for key 'kernel_kbd_events_queue_capacity': %s shouldn't be above 65535.\n",conf->pairs[i].value); + return EFI_INVALID_PARAMETER; + } else if (cap<64) { + Print(L"[BlastConf] Error for key 'kernel_kbd_events_queue_capacity': %s shouldn't be below 64.\n",conf->pairs[i].value); + return EFI_INVALID_PARAMETER; + } + (*boot_conf)->kernel_kbd_events_queue_capacity=cap; + } } } return status; diff --git a/Blastproof/src/libs/src/console.c b/Blastproof/src/libs/src/console.c index 490c9a0..6690dd4 100644 --- a/Blastproof/src/libs/src/console.c +++ b/Blastproof/src/libs/src/console.c @@ -1,10 +1,86 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/console.h" +#include "../include/layout.h" #include #include #include +#include #include #include +#include #include +#include +VOID bp_console_clear_screen() { + gST->ConOut->ClearScreen(gST->ConOut); + return; +} +VOID bp_console_set_console_mode() { + UINTN current_mode=gST->ConOut->Mode->Mode; + UINTN max_cols; + UINTN max_rows; + UINTN new_mode=current_mode; + EFI_STATUS status=gST->ConOut->QueryMode(gST->ConOut,current_mode,&max_cols,&max_rows); + if (EFI_ERROR(status)) { + Print(L"[BlastConsole] Error: couldn't identify current mode.\n"); + while (TRUE) {}; + } + for (INT32 mode=0;modeConOut->Mode->MaxMode;mode++) { + UINTN cols; + UINTN rows; + if (EFI_ERROR(gST->ConOut->QueryMode(gST->ConOut,mode,&cols,&rows))) { + continue; + } + if ((cols>max_cols && !(rowsmax_rows && !(colsConOut->SetMode(gST->ConOut,new_mode); + if (!EFI_ERROR(status)) { + bp_console_clear_screen(); + } + return; +} +EFI_STATUS bp_console_clear_row(UINTN row) { + UINTN current_mode=gST->ConOut->Mode->Mode; + UINTN cols; + UINTN rows; + EFI_STATUS status=gST->ConOut->QueryMode(gST->ConOut,current_mode,&cols,&rows); + if (EFI_ERROR(status)) { + Print(L"[BlastConsole] Error: couldn't identify current mode.\n"); + while (TRUE) {}; + } + if (row>=rows) return EFI_INVALID_PARAMETER; + CHAR16 *buf=AllocatePool(sizeof(CHAR16)*cols+2); + if (buf==NULL) return EFI_OUT_OF_RESOURCES; + for (int i=0;iConOut->SetCursorPosition(gST->ConOut,0,row); + Print(buf); + FreePool(buf); + return EFI_SUCCESS; +} +EFI_STATUS bp_console_write_centered(CHAR16 *text,UINTN row) { + if (text==NULL) return EFI_INVALID_PARAMETER; + UINTN current_mode=gST->ConOut->Mode->Mode; + UINTN cols; + UINTN rows; + EFI_STATUS status=gST->ConOut->QueryMode(gST->ConOut,current_mode,&cols,&rows); + if (EFI_ERROR(status)) { + Print(L"[BlastConsole] Error: couldn't identify current mode.\n"); + while (TRUE) {}; + } + if (row>=rows) return EFI_INVALID_PARAMETER; + UINTN text_len=StrnLenS(text,cols); + UINTN starting_x=(cols/2)-(text_len/2); + bp_console_clear_row(row); + gST->ConOut->SetCursorPosition(gST->ConOut,starting_x,row); + Print(L"%s",text); + return EFI_SUCCESS; +} VOID bp_console_print_file(bp_disk_FILE *file) { for (UINTN i=0;ifile_size_bytes;i++) { CHAR8 c=file->content[i]; @@ -15,12 +91,25 @@ VOID bp_console_print_file(bp_disk_FILE *file) { } } } -EFI_STATUS bp_console_read_password(CHAR16 *prompt,bp_console_PASSWORD **pwd,CHAR16 hiding_char) { +EFI_STATUS bp_console_read_password(CHAR16 *prompt,bp_console_PASSWORD **pwd) { EFI_STATUS status; if (prompt==NULL || pwd==NULL) { return EFI_INVALID_PARAMETER; } - Print(L"%s",prompt); + UINTN index=BP_CONSOLE_DEFAULT_LAYOUT_INDEX; + UINTN layout_count=bp_layout_get_layout_count(); + if (layout_count==0) return EFI_NOT_FOUND; + CHAR16 **layouts=bp_layout_get_layout_list(); + UINTN current_mode=gST->ConOut->Mode->Mode; + UINTN cols; + UINTN rows; + status=gST->ConOut->QueryMode(gST->ConOut,current_mode,&cols,&rows); + if (EFI_ERROR(status)) { + Print(L"[BlastConsole] Error: couldn't identify current mode.\n"); + while (TRUE) {}; + } + bp_console_write_centered(prompt,rows/2-3); + gST->ConOut->EnableCursor(gST->ConOut,FALSE); EFI_INPUT_KEY key; UINTN buf_size=16; UINTN length=0; @@ -28,6 +117,14 @@ EFI_STATUS bp_console_read_password(CHAR16 *prompt,bp_console_PASSWORD **pwd,CHA if (buffer==NULL) { return EFI_OUT_OF_RESOURCES; } + bp_console_write_centered(L"[No input detected yet]",rows/2-1); + bp_console_write_centered(L"Current keyboard layout:",rows/2+1); + CHAR16 layout_buf[128]; + UnicodeSPrint(layout_buf,sizeof(layout_buf),L"<- %s (%d/%d) ->",layouts[index],index+1,layout_count); + bp_console_write_centered(layout_buf,rows/2+2); + bp_console_write_centered(L"[F1] Shutdown device",rows/2+4); + bp_console_write_centered(L"[F2] Reboot device ",rows/2+5); + bp_console_write_centered(L"[F3] UEFI firmware ",rows/2+6); while (TRUE) { status=gST->ConIn->ReadKeyStroke(gST->ConIn,&key); if (status==EFI_NOT_READY) { @@ -38,10 +135,39 @@ EFI_STATUS bp_console_read_password(CHAR16 *prompt,bp_console_PASSWORD **pwd,CHA } if (key.UnicodeChar==CHAR_CARRIAGE_RETURN) { break; + } else if (key.ScanCode==SCAN_RIGHT) { + index=(index+1)%layout_count; + UnicodeSPrint(layout_buf,sizeof(layout_buf),L"<- %s (%d/%d) ->",layouts[index],index+1,layout_count); + bp_console_write_centered(layout_buf,rows/2+2); + } else if (key.ScanCode==SCAN_LEFT) { + index=(index+layout_count-1)%layout_count; + UnicodeSPrint(layout_buf,sizeof(layout_buf),L"<- %s (%d/%d) ->",layouts[index],index+1,layout_count); + bp_console_write_centered(layout_buf,rows/2+2); + } else if (key.ScanCode==SCAN_F1) { + gRT->ResetSystem(EfiResetShutdown,EFI_SUCCESS,0,NULL); + } else if (key.ScanCode==SCAN_F2) { + gRT->ResetSystem(EfiResetCold,EFI_SUCCESS,0,NULL); + } else if (key.ScanCode==SCAN_F3) { + UINT64 os_indications; + UINTN size=sizeof(os_indications); + status=gRT->GetVariable(L"OsIndications",&gEfiGlobalVariableGuid,NULL,&size,&os_indications); + if (EFI_ERROR(status)) os_indications=0; + os_indications|=EFI_OS_INDICATIONS_BOOT_TO_FW_UI; + status=gRT->SetVariable(L"OsIndications",&gEfiGlobalVariableGuid,EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,sizeof(os_indications),&os_indications); + if (!EFI_ERROR(status)) { + gRT->ResetSystem(EfiResetCold,EFI_SUCCESS,0,NULL); + } else { + bp_console_write_centered(L"Reboot to firmware failed. Please reboot manually.",rows/2+8); + } } else if (key.UnicodeChar==CHAR_BACKSPACE) { if (length>0) { length--; - Print(L"\b \b"); + buffer[length]='\0'; + if (length==0) { + bp_console_write_centered(L"[No input detected yet]",rows/2-1); + } else { + bp_console_write_centered(L"[Hidden input active]",rows/2-1); + } } } else if (key.UnicodeChar>=L' ' && key.UnicodeChar<=0x7E) { if (length+1>=buf_size) { @@ -50,18 +176,16 @@ EFI_STATUS bp_console_read_password(CHAR16 *prompt,bp_console_PASSWORD **pwd,CHA FreePool(buffer); return EFI_OUT_OF_RESOURCES; } - CopyMem(new_buf,buffer,length*sizeof(CHAR16)); + CopyMem(new_buf,buffer,(length+1)*sizeof(CHAR16)); FreePool(buffer); buffer=new_buf; buf_size*=2; } - buffer[length]=key.UnicodeChar; - length++; - if (hiding_char!=0) { - Print(L"%c",hiding_char); - } else { - Print(L"%c",key.UnicodeChar); + buffer[length]=bp_layout_convert_char(key.UnicodeChar,index); + if (length==0) { + bp_console_write_centered(L"[Hidden input active]",rows/2-1); } + length++; } } buffer[length]=L'\0'; @@ -72,6 +196,7 @@ EFI_STATUS bp_console_read_password(CHAR16 *prompt,bp_console_PASSWORD **pwd,CHA } (*pwd)->password=buffer; (*pwd)->size=length; - Print(L"\n"); + bp_console_clear_screen(); + gST->ConOut->SetCursorPosition(gST->ConOut,0,0); return EFI_SUCCESS; } diff --git a/Blastproof/src/libs/src/cpu.c b/Blastproof/src/libs/src/cpu.c deleted file mode 100644 index 2bcca4f..0000000 --- a/Blastproof/src/libs/src/cpu.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "../include/cpu.h" -#include -#include -EFI_STATUS bp_cpu_fill_cpu_info(bp_cpu_CPU_INFO* cpu_info) { - UINT32 Eax,Ebx,Ecx,Edx; - AsmCpuid(0,&Eax,&Ebx,&Ecx,&Edx); - *(UINT32 *)&cpu_info->vendor[0]=Ebx; - *(UINT32 *)&cpu_info->vendor[4]=Edx; - *(UINT32 *)&cpu_info->vendor[8]=Ecx; - cpu_info->vendor[12]='\0'; - cpu_info->max_cpuid_level=Eax; - AsmCpuid(1,&Eax,&Ebx,&Ecx,&Edx); - cpu_info->stepping=Eax&0xF; - cpu_info->model=(Eax>>4)&0xF; - cpu_info->family=(Eax>>8)&0xF; - cpu_info->ext_model=(Eax>>16)&0xF; - cpu_info->ext_family=(Eax>>20)&0xFF; - cpu_info->display_family=cpu_info->family+(cpu_info->family==0xF?cpu_info->ext_family:0); - cpu_info->display_model=cpu_info->family+((cpu_info->family==0x6||cpu_info->family==0xF)?(cpu_info->ext_model<<4):0); - for (INTN i=0;i<32;i++) { - cpu_info->ecx_bin[i]=(Ecx&(1<<(31-i)))?L'1':L'0'; - } - cpu_info->ecx_bin[32]=L'\0'; - for (INTN i=0;i<32;i++) { - cpu_info->edx_bin[i]=(Edx&(1<<(31-i)))?L'1':L'0'; - } - cpu_info->edx_bin[32]=L'\0'; - return 0; -} diff --git a/Blastproof/src/libs/src/crypto.c b/Blastproof/src/libs/src/crypto.c index a795816..944717d 100644 --- a/Blastproof/src/libs/src/crypto.c +++ b/Blastproof/src/libs/src/crypto.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/crypto.h" #include "../sha3/sha3.h" #include "../argon2/argon2.h" diff --git a/Blastproof/src/libs/src/debug.c b/Blastproof/src/libs/src/debug.c index 9523175..d0acc89 100644 --- a/Blastproof/src/libs/src/debug.c +++ b/Blastproof/src/libs/src/debug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/debug.h" #include #include diff --git a/Blastproof/src/libs/src/disk.c b/Blastproof/src/libs/src/disk.c index 2543372..a68a0db 100644 --- a/Blastproof/src/libs/src/disk.c +++ b/Blastproof/src/libs/src/disk.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/disk.h" #include #include diff --git a/Blastproof/src/libs/src/font.c b/Blastproof/src/libs/src/font.c index 64cc0e5..8244d61 100644 --- a/Blastproof/src/libs/src/font.c +++ b/Blastproof/src/libs/src/font.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/font.h" #include #include diff --git a/Blastproof/src/libs/src/graphic.c b/Blastproof/src/libs/src/graphic.c index e5a5bd1..f670b68 100644 --- a/Blastproof/src/libs/src/graphic.c +++ b/Blastproof/src/libs/src/graphic.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/graphic.h" -#include "ProcessorBind.h" -#include "Uefi/UefiBaseType.h" #include #include #include @@ -99,7 +98,7 @@ STATIC UINT32 bp_graphic_get_width_from_mask (UINT32 mask) { } return width; } -UINT32 bp_graphic_get_pixel_by_color (bp_graphic_COLOR_RGB *color,UINT32 red_bits,UINT32 green_bits,UINT32 blue_bits) { +UINT32 bp_graphic_get_pixel_by_color(bp_graphic_COLOR_RGB *color,UINT32 red_bits,UINT32 green_bits,UINT32 blue_bits) { UINT32 pixel=0; UINT32 r_shift=bp_graphic_get_shift_from_mask(red_bits); UINT32 g_shift=bp_graphic_get_shift_from_mask(green_bits); diff --git a/Blastproof/src/libs/src/initfs.c b/Blastproof/src/libs/src/initfs.c index 9974bfc..9a3c74d 100644 --- a/Blastproof/src/libs/src/initfs.c +++ b/Blastproof/src/libs/src/initfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/initfs.h" #include "../include/crypto.h" #include @@ -53,7 +54,7 @@ EFI_STATUS bp_initfs_check_initfs_header(bp_initfs_INITFS_HEADER *header,EFI_FIL } EFI_FILE_PROTOCOL *opened_file=NULL; EFI_STATUS status; - status=bp_disk_open_file(root,L"\\EFI\\BlastProofFiles\\initfs-footprint.bin",&opened_file); + status=bp_disk_open_file(root,L"\\EFI\\BPFILES\\INITFSFP.BIN",&opened_file); if (EFI_ERROR(status)) { return status; } @@ -150,7 +151,7 @@ EFI_STATUS bp_initfs_check_signsyst_header(bp_initfs_SIGNSYST_HEADER *header,EFI return EFI_SECURITY_VIOLATION; } EFI_FILE_PROTOCOL *opened_file=NULL; - status=bp_disk_open_file(root,L"\\EFI\\BlastProofFiles\\signsyst-hash.bin",&opened_file); + status=bp_disk_open_file(root,L"\\EFI\\BPFILES\\SSHASH.BIN",&opened_file); if (EFI_ERROR(status)) { return status; } diff --git a/Blastproof/src/libs/src/layout.c b/Blastproof/src/libs/src/layout.c new file mode 100644 index 0000000..4776016 --- /dev/null +++ b/Blastproof/src/libs/src/layout.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "../include/layouts/layout_registry.h" +#include +#include +#include +#include +#include +CHAR16 **bp_layout_get_layout_list() { + return layout_list; +} +UINTN bp_layout_get_layout_count() { + return layout_count; +} +CHAR16 bp_layout_convert_char(CHAR16 source,UINTN layout_index) { + bp_layout_CONV_TABLE *layout_conversion=layout_conversions_table[layout_index]; + for (UINTN i=0;iconv_count;i++) { + if (layout_conversion->conv_table[i].char_source==source) { + return layout_conversion->conv_table[i].char_dest; + } + } + return source; +} diff --git a/Blastproof/src/libs/src/ui.c b/Blastproof/src/libs/src/ui.c index 4274ed1..31eeeb1 100644 --- a/Blastproof/src/libs/src/ui.c +++ b/Blastproof/src/libs/src/ui.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/ui.h" #include "../include/graphic.h" #include "../include/debug.h" diff --git a/Blastproof/src/libs/src/vftm.c b/Blastproof/src/libs/src/vftm.c new file mode 100644 index 0000000..c197e31 --- /dev/null +++ b/Blastproof/src/libs/src/vftm.c @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "../include/vftm.h" +#include "../include/crypto.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +bp_vftm_VFTM_ASSETS assets; +static VOID generate_vftm_sectors(const UINT8* part_guid,UINTN* s1,UINTN* s2) { + UINT32 h=0x811c9dc5; + for (UINTN i=0;i<16;i++) h=(h^part_guid[i])*0x01000193; + *s1=8+(h%24); + *s2=8+(((h>>16)%23+(*s1-7))%24); +} +EFI_STATUS bp_vftm_get_vftm_assets(EFI_HANDLE image_handle) { + EFI_LOADED_IMAGE_PROTOCOL *loaded_image; + EFI_STATUS status=gBS->HandleProtocol(image_handle,&gEfiLoadedImageProtocolGuid,(VOID**)&loaded_image); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: can't get LoadedImage.\n"); + while (TRUE) {}; + } else { + Print(L"[BlastVFTM] LoadedImage acquired.\n"); + } + EFI_BLOCK_IO_PROTOCOL *block_io_esp=NULL; + status=gBS->HandleProtocol(loaded_image->DeviceHandle,&gEfiBlockIoProtocolGuid,(VOID **)&block_io_esp); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: can't get BlockIo.\n"); + while (TRUE) {}; + } else { + Print(L"[BlastVFTM] BlockIo on LoadedImage acquired.\n"); + } + if (!block_io_esp->Media->LogicalPartition) { + Print(L"[BlastVFTM] Error: BlockIo on LoadedImage isn't a partition.\n"); + while (TRUE) {}; + } + EFI_DEVICE_PATH_PROTOCOL *full_path; + status=gBS->OpenProtocol(loaded_image->DeviceHandle,&gEfiDevicePathProtocolGuid,(VOID**)&full_path,image_handle,NULL,EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't get full device path for LoadedImage. Status: %d\n",status); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Full device path for LoadedImage acquired.\n"); + EFI_DEVICE_PATH_PROTOCOL *parent_path=DuplicateDevicePath(full_path); + if (parent_path==NULL) { + Print(L"[BlastVFTM] Error: couldn't duplicate full path to parent path.\n"); + while (TRUE) {}; + } + EFI_DEVICE_PATH_PROTOCOL *node; + node=parent_path; + while (!IsDevicePathEnd(NextDevicePathNode(node))) { + node=NextDevicePathNode(node); + } + if (DevicePathType(node)!=MEDIA_DEVICE_PATH || DevicePathSubType(node)!=MEDIA_HARDDRIVE_DP) { + FreePool(parent_path); + Print(L"[BlastVFTM] Error: couldn't find a valid disk device path.\n"); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Found a valid disk device path.\n"); + SetDevicePathEndNode(node); + EFI_DEVICE_PATH_PROTOCOL *remaining_path=parent_path; + EFI_HANDLE disk_handle; + status=gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&remaining_path,&disk_handle); + FreePool(parent_path); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't obtain disk handle.\n"); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Obtained disk handle.\n"); + EFI_BLOCK_IO_PROTOCOL *disk_blockio=NULL; + status=gBS->OpenProtocol(disk_handle,&gEfiBlockIoProtocolGuid,(VOID**)&disk_blockio,image_handle,NULL,EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't obtain disk BlockIO. Status: %d\n",status); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Obtained disk BlockIO.\n"); + if (disk_blockio->Media->LogicalPartition) { + Print(L"[BlastVFTM] Error: media is a partition.\n"); + while (TRUE) {}; + } + if (disk_blockio->Media->BlockSize!=512) { + Print(L"[BlastVFTM] Error: disk doesn't have a block size of 512.\n"); + while (TRUE) {}; + } + assets.block_io_disk=disk_blockio; + UINT8 *gpt_buffer=AllocatePool(512); + if (!gpt_buffer) { + Print(L"[BlastVFTM] Error: out of memory for GPT Header.\n"); + while (TRUE) {}; + } + status=disk_blockio->ReadBlocks(disk_blockio,disk_blockio->Media->MediaId,1,512,gpt_buffer); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't read first LBA of the disk.\n"); + while (TRUE) {}; + } + EFI_PARTITION_TABLE_HEADER *gpt_header=(EFI_PARTITION_TABLE_HEADER*)gpt_buffer; + if (gpt_header->Header.Signature!=EFI_PTAB_HEADER_ID) { + Print(L"[BlastVFTM] Error: first LBA of the disk isn't a GPT table.\n"); + while (TRUE) {}; + } + CopyMem(assets.disk_guid,&gpt_header->DiskGUID,sizeof(gpt_header->DiskGUID)); + Print(L"[BlastVFTM] Successfully obtained disk GUID.\n"); + UINTN parts_size=gpt_header->NumberOfPartitionEntries*gpt_header->SizeOfPartitionEntry; + UINT8 *partition_table_buffer=AllocatePool(parts_size); + if (!partition_table_buffer) { + Print(L"[BlastVFTM] Error: out of memory for partitions entries.\n"); + while (TRUE) {}; + } + status=disk_blockio->ReadBlocks(disk_blockio,disk_blockio->Media->MediaId,gpt_header->PartitionEntryLBA,parts_size,partition_table_buffer); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't read partition entries.\n"); + while (TRUE) {}; + } + assets.partition_table_buffer=partition_table_buffer; + EFI_PARTITION_ENTRY *entry=(EFI_PARTITION_ENTRY*)partition_table_buffer; + INTN esp_part_index=-1; + for (UINTN i=0;iNumberOfPartitionEntries;i++) { + EFI_PARTITION_ENTRY *current=&entry[i]; + if (CompareGuid(¤t->PartitionTypeGUID,&gEfiPartTypeSystemPartGuid)) { + esp_part_index=i; + break; + } + } + if (esp_part_index<0) { + Print(L"[BlastVFTM] Error: couldn't found any ESP partition.\n"); + while (TRUE) {}; + } + assets.part_count=gpt_header->NumberOfPartitionEntries; + EFI_PARTITION_ENTRY esp_entry=entry[esp_part_index]; + CopyMem(assets.efi_part_unique_guid,&esp_entry.UniquePartitionGUID,sizeof(esp_entry.UniquePartitionGUID)); + Print(L"[BlastVFTM] Successfully obtained ESP partition unique GUID.\n"); + UINTN s_manifest,s_pk_manifest; + generate_vftm_sectors(assets.efi_part_unique_guid,&s_manifest,&s_pk_manifest); + UINT8 *vftm_buffer=AllocatePool(512); + if (!vftm_buffer) { + Print(L"[BlastVFTM] Error: out of memory for manifest.\n"); + while (TRUE) {}; + } + status=block_io_esp->ReadBlocks(block_io_esp,block_io_esp->Media->MediaId,s_manifest,512,vftm_buffer); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't read manifest.\n"); + while (TRUE) {}; + } + CopyMem(&assets.manifest,vftm_buffer,sizeof(assets.manifest)); + Print(L"[BlastVFTM] Successfully obtained manifest.\n"); + UINT8 *pk_manifest_buffer=AllocatePool(512); + if (!pk_manifest_buffer) { + Print(L"[BlastVFTM] Error: out of memory for manifest public key.\n"); + while (TRUE) {}; + } + status=block_io_esp->ReadBlocks(block_io_esp,block_io_esp->Media->MediaId,s_pk_manifest,512,pk_manifest_buffer); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't read manifest public key.\n"); + while (TRUE) {}; + } + CopyMem(&assets.pk_manifest,pk_manifest_buffer,sizeof(assets.pk_manifest)); + Print(L"[BlastVFTM] Successfully obtained manifest public key.\n"); + UINTN signature_size_padded=(assets.manifest.signature_size+511) & ~511; + if (assets.manifest.signature_offset_bytes%512!=0) { + Print(L"[BlastVFTM] Error: provided signature offset isn't a multiple of 512.\n"); + while (TRUE) {}; + } + UINT8 *signature_buffer=AllocatePool(signature_size_padded); + if (!signature_buffer) { + Print(L"[BlastVFTM] Error: out of memory for manifest signature.\n"); + while (TRUE) {}; + } + status=block_io_esp->ReadBlocks(block_io_esp,block_io_esp->Media->MediaId,assets.manifest.signature_offset_bytes/512,signature_size_padded,signature_buffer); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't read manifest signature. Status: %d\n",status); + while (TRUE) {}; + } + assets.manifest_signature=signature_buffer; + Print(L"[BlastVFTM] Successfully obtained manifest signature.\n"); + assets.block_io_esp=block_io_esp; + return EFI_SUCCESS; +} +EFI_STATUS bp_vftm_check_manifest_authenticity(UINT8 *pk_root,UINT8* sig_root) { + if (pk_root==NULL || sig_root==NULL) return EFI_INVALID_PARAMETER; + EFI_STATUS status=bp_crypto_sphincsplus_verify(sig_root,CRYPTO_BYTES,assets.pk_manifest,sizeof(assets.pk_manifest),pk_root); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: critical security violation in boot process:\n",status); + Print(L"[BlastVFTM] Provided manifest public key couldn't be authentified.\n",status); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Successfully authentified manifest public key.\n",status); + status=bp_crypto_sphincsplus_verify(assets.manifest_signature,CRYPTO_BYTES,(UINT8*)&assets.manifest,sizeof(assets.manifest),assets.pk_manifest); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: critical security violation in boot process:\n",status); + Print(L"[BlastVFTM] Provided Vystem FAT Trusted Manifest couldn't be authentified.\n",status); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Successfully authentified provided Vystem FAT Trusted Manifest.\n",status); + return EFI_SUCCESS; +} +EFI_STATUS bp_vftm_check_manifest_content() { + UINT8 sig[8]=BP_VFTM_SIGNATURE; + for (int i=0;i<8;i++) { + if (sig[i]!=assets.manifest.sig[i]) { + Print(L"[BlastVFTM] Error: invalid manifest signature.\n"); + while (TRUE) {}; + } + } + if (assets.manifest.manifest_version!=BP_VFTM_SUPPORTED_MANIFEST_VERSION) { + Print(L"[BlastVFTM] Error: non supported manifest version.\n"); + while (TRUE) {}; + } + if (assets.manifest.os_version!=BP_VFTM_SUPPORTED_OS_VERSION) { + Print(L"[BlastVFTM] Error: wrong OS version.\n"); + while (TRUE) {}; + } + if (assets.manifest.bootloader_version!=BP_VFTM_SUPPORTED_BOOTLOADER_VERSION) { + Print(L"[BlastVFTM] Error: wrong bootloader version.\n"); + while (TRUE) {}; + } + if (CompareMem(assets.manifest.gpt_disk_guid,assets.disk_guid,16)!=0) { + Print(L"[BlastVFTM] Error: manifest disk GUID doesn't correspond with GPT table disk GUID.\n"); + while (TRUE) {}; + } + if (CompareMem(assets.manifest.gpt_efi_part_unique_guid,assets.efi_part_unique_guid,16)!=0) { + Print(L"[BlastVFTM] Error: manifest ESP unique GUID doesn't correspond with GPT table ESP unique GUID.\n"); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Successfully verified versions, disk and partitions informations from manifest.\n"); + UINT8* fat32_header_buffer=AllocatePool(512); + if (!fat32_header_buffer) { + Print(L"[BlastVFTM] Error: out of memory for FAT32 header buffer.\n"); + while (TRUE) {}; + } + EFI_STATUS status=assets.block_io_esp->ReadBlocks(assets.block_io_esp,assets.block_io_esp->Media->MediaId,0,512,fat32_header_buffer); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't ESP FAT32 header. Status: %d\n",status); + while (TRUE) {}; + } + bp_vftm_FAT32_HEADER *fat32_header=(bp_vftm_FAT32_HEADER*)fat32_header_buffer; + bp_crypto_HASH_DIGEST *header_hash; + status=bp_crypto_sha3((UINT8*)fat32_header,sizeof(bp_vftm_FAT32_HEADER),64,&header_hash); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't hash FAT32 header.\n"); + while (TRUE) {}; + } + if (CompareMem(header_hash->digest,assets.manifest.fat_header_hash,header_hash->size_bytes)!=0) { + Print(L"[BlastVFTM] Error: FAT32 header hash didn't correspond with manifest FAT32 header hash.\n"); + while (TRUE) {}; + } + UINTN fat_total_sectors=fat32_header->BPB_FATSz32*fat32_header->BPB_NumFATs; + UINTN data_start_sector=fat32_header->BPB_RsvdSecCnt+fat_total_sectors; + UINTN data_total_sectors=fat32_header->BPB_TotSec32-data_start_sector; + UINTN data_clusters=data_total_sectors/fat32_header->BPB_SecPerClus; + if (data_clusters!=assets.manifest.clusters_count) { + Print(L"[BlastVFTM] Error: FAT32 header indicate a wrong amount of data clusters.\n"); + while (TRUE) {}; + } + if (fat32_header->BPB_BytsPerSec!=assets.manifest.bytes_per_sector) { + Print(L"[BlastVFTM] Error: FAT32 header indicate a wrong amount of bytes per sector.\n"); + while (TRUE) {}; + } + if (fat32_header->BPB_SecPerClus!=assets.manifest.sectors_per_cluster) { + Print(L"[BlastVFTM] Error: FAT32 header indicate a wrong amount of sector per cluster.\n"); + while (TRUE) {}; + } + if (fat32_header->BPB_FATSz32*fat32_header->BPB_BytsPerSec!=assets.manifest.fat_size_bytes) { + Print(L"[BlastVFTM] Error: FAT32 header indicate a wrong amount of bytes per FAT.\n"); + while (TRUE) {}; + } + if (fat32_header->BPB_RsvdSecCnt*fat32_header->BPB_BytsPerSec!=assets.manifest.fat_offset_bytes) { + Print(L"[BlastVFTM] Error: FAT32 header indicate a wrong amount of bytes per FAT.\n"); + while (TRUE) {}; + } + if (CompareMem(fat32_header->BS_OEMName,"VYBUILD1",8)!=0) { + Print(L"[BlastVFTM] Warning: OEM name indicated in FAT32 header isn't the expected OEM name: %s\n",fat32_header->BS_OEMName); + } + if (CompareMem(fat32_header->BS_VolLab,"VYAUTOFAT32",11)!=0) { + Print(L"[BlastVFTM] Warning: Volume name indicated in FAT32 header isn't the expected volume name: %s\n",fat32_header->BS_VolLab); + } + Print(L"[BlastVFTM] Successfully verified ESP FAT32 header.\n"); + UINT8* fat32_fat_buffer=AllocatePool(assets.manifest.fat_size_bytes*2); + if (!fat32_fat_buffer) { + Print(L"[BlastVFTM] Error: out of memory for FAT32 double FAT buffer.\n"); + while (TRUE) {}; + } + status=assets.block_io_esp->ReadBlocks(assets.block_io_esp,assets.block_io_esp->Media->MediaId,assets.manifest.fat_offset_bytes/512,assets.manifest.fat_size_bytes*2,fat32_fat_buffer); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't read ESP FAT32 double FAT. Status: %d\n",status); + while (TRUE) {}; + } + UINT32 *f1=(UINT32*)fat32_fat_buffer; + UINT32 *f2=(UINT32*)(fat32_fat_buffer+assets.manifest.fat_size_bytes); + f1[0]=f1[1]=f2[0]=f2[1]=0; + bp_crypto_HASH_DIGEST *fat1_hash; + bp_crypto_HASH_DIGEST *fat2_hash; + status=bp_crypto_sha3((UINT8*)fat32_fat_buffer,assets.manifest.fat_size_bytes,64,&fat1_hash); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't hash FAT32 first FAT.\n"); + while (TRUE) {}; + } + status=bp_crypto_sha3((UINT8*)fat32_fat_buffer+assets.manifest.fat_size_bytes,assets.manifest.fat_size_bytes,64,&fat2_hash); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't hash FAT32 second FAT.\n"); + while (TRUE) {}; + } + if (CompareMem(fat1_hash->digest,assets.manifest.fat_hash,fat1_hash->size_bytes)!=0) { + Print(L"[BlastVFTM] Error: FAT32 first FAT hash didn't correspond with manifest FAT32 fat hash.\n"); + while (TRUE) {}; + } + if (CompareMem(fat2_hash->digest,assets.manifest.fat_hash,fat2_hash->size_bytes)!=0) { + Print(L"[BlastVFTM] Error: FAT32 second FAT hash didn't correspond with manifest FAT32 fat hash\nA firmware that dump things on the ESP partition can cause the VFTM check to fail.\nConsider adding a VAR file or equivalent to your VM if that is not the case.\n"); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Successfully verified all ESP FATs.\n"); + UINTN bytes_per_cluster=fat32_header->BPB_BytsPerSec*fat32_header->BPB_SecPerClus; + UINT8* bootloader_buffer=AllocatePool(assets.manifest.bootloader_cluster_count*bytes_per_cluster); + if (!bootloader_buffer) { + Print(L"[BlastVFTM] Error: out of memory for bootloader buffer.\n"); + while (TRUE) {}; + } + UINTN lba_data_start=fat32_header->BPB_RsvdSecCnt+(fat32_header->BPB_NumFATs*fat32_header->BPB_FATSz32); + UINTN bootloader_lba=lba_data_start+(assets.manifest.bootloader_cluster_offset-2); + status=assets.block_io_esp->ReadBlocks(assets.block_io_esp,assets.block_io_esp->Media->MediaId,bootloader_lba,assets.manifest.bootloader_cluster_count*bytes_per_cluster,bootloader_buffer); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't read bootloader. Status: %d\n",status); + while (TRUE) {}; + } + bp_crypto_HASH_DIGEST *bootloader_hash; + status=bp_crypto_sha3((UINT8*)bootloader_buffer,assets.manifest.bootloader_cluster_count*bytes_per_cluster,64,&bootloader_hash); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't hash bootloader.\n"); + while (TRUE) {}; + } + if (CompareMem(bootloader_hash->digest,assets.manifest.bootloader_binary_hash,bootloader_hash->size_bytes)!=0) { + Print(L"[BlastVFTM] Error: bootloader hash doesn't correspond with manifest bootloader hash.\n"); + while (TRUE) {}; + } + FreePool(bootloader_buffer); + Print(L"[BlastVFTM] Successfully verified bootloader.\n"); + bp_crypto_HASH_DIGEST *manifest_hash; + status=bp_crypto_sha3((UINT8*)&assets.manifest,sizeof(assets.manifest)-64,64,&manifest_hash); + if (EFI_ERROR(status)) { + Print(L"[BlastVFTM] Error: couldn't hash manifest.\n"); + while (TRUE) {}; + } + if (CompareMem(manifest_hash->digest,assets.manifest.manifest_hash,manifest_hash->size_bytes)!=0) { + Print(L"[BlastVFTM] Error: manifest hash doesn't correspond with the indicated hash inside the manifest.\n"); + while (TRUE) {}; + } + Print(L"[BlastVFTM] Successfully verified manifest.\n"); + Print(L"[BlastVFTM] All VFTM check passed. Launching SBFIE UI...\n"); + return EFI_SUCCESS; +} +bp_vftm_VFTM_ASSETS *bp_vftm_get_assets() { + return &assets; +} diff --git a/Blastproof/src/libs/src/vyx.c b/Blastproof/src/libs/src/vyx.c index 3c7fd36..b2abe39 100644 --- a/Blastproof/src/libs/src/vyx.c +++ b/Blastproof/src/libs/src/vyx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include "../include/vyx.h" #include "Base.h" #include @@ -16,6 +17,7 @@ #define PAGE_NX (1ULL << 63) static BOOLEAN is_allocator_init=FALSE; static UINT64 pt_pool_page_offset=0; +static UINT8 payload_sig[8]={'V','P','A','Y','L','O','A','D'}; UINTN pad_size(UINTN value,UINTN multiple) { if (multiple==0) return value; UINTN remainder=value%multiple; @@ -39,7 +41,7 @@ EFI_STATUS bp_vyx_get_header(bp_disk_FILE *file,bp_vyx_VYX_HEADER **header) { } return EFI_SUCCESS; } -EFI_STATUS bp_vyx_create_shelter_boot_conf(UINT8 log_level,BOOLEAN test_benchmark,UINT64 bench_iterations,BOOLEAN log_disable_serial_port,BOOLEAN disable_serial_port,UINT16 log_ring_size,bp_vyx_SHELTER_BOOT_CONFIG *boot_config) { +EFI_STATUS bp_vyx_create_shelter_boot_conf(UINT8 log_level,BOOLEAN test_benchmark,UINT64 bench_iterations,BOOLEAN log_disable_serial_port,BOOLEAN disable_serial_port,UINT16 log_ring_size,UINT64 acpi_rsdp,UINT8 acpi_ver,UINT16 kbd_events_queue_capacity,bp_vyx_SHELTER_BOOT_CONFIG *boot_config) { if (boot_config==NULL) { return EFI_INVALID_PARAMETER; } @@ -49,6 +51,9 @@ EFI_STATUS bp_vyx_create_shelter_boot_conf(UINT8 log_level,BOOLEAN test_benchmar boot_config->log_disable_serial_port=log_disable_serial_port; boot_config->disable_serial_port=disable_serial_port; boot_config->log_ring_size=log_ring_size; + boot_config->acpi_rsdp=acpi_rsdp; + boot_config->acpi_ver=acpi_ver; + boot_config->kbd_events_queue_capacity=kbd_events_queue_capacity; UINT8 sig_start[8]={'S','h','C','f','g','B','e','g'}; UINT8 sig_end[8]={'S','h','C','f','g','E','n','d'}; for (UINTN i=0;i<8;i++) {boot_config->sig_start[i]=sig_start[i];boot_config->sig_end[i]=sig_end[i];}; @@ -150,7 +155,8 @@ EFI_STATUS bp_vyx_setup_physical_pages(bp_vyx_VYX_HEADER *header,bp_disk_FILE *v FreePool(*loader_setting); return status; } - status=gBS->AllocatePages(AllocateAnyPages,EfiLoaderCode,BP_VYX_SHELTER_PT_PAGE_COUNT,&(*loader_setting)->shelter_page_table_addr_phys); + (*loader_setting)->shelter_page_table_addr_phys=0xFFFFFFFF; + status=gBS->AllocatePages(AllocateMaxAddress,EfiLoaderCode,BP_VYX_SHELTER_PT_PAGE_COUNT,&(*loader_setting)->shelter_page_table_addr_phys); if (EFI_ERROR(status)) { FreePool(*loader_setting); return status; @@ -168,17 +174,77 @@ EFI_STATUS bp_vyx_setup_physical_pages(bp_vyx_VYX_HEADER *header,bp_disk_FILE *v SetMem((VOID*)(UINTN)(*loader_setting)->shelter_logging_ring_buffer_addr_phys,shelter_boot_config->log_ring_size*4096,0); (*loader_setting)->shelter_logging_ring_buffer_pages_count=MAX(shelter_boot_config->log_ring_size,4); CopyMem((VOID*)(UINTN)(*loader_setting)->text_addr_phys,vyx_file->content+sizeof(bp_vyx_VYX_HEADER),header->text_size_padded); + UINT8 *payload_cur=vyx_file->content+sizeof(bp_vyx_VYX_HEADER)+header->text_size_padded; if (data_size!=0 && rodata_size!=0) { CopyMem((VOID*)(UINTN)(*loader_setting)->data_addr_phys,vyx_file->content+sizeof(bp_vyx_VYX_HEADER)+header->text_size_padded,header->data_size_padded); CopyMem((VOID*)(UINTN)(*loader_setting)->rodata_addr_phys,vyx_file->content+sizeof(bp_vyx_VYX_HEADER)+header->text_size_padded+header->data_size_padded,header->rodata_size_padded); + payload_cur+=(header->data_size_padded+header->rodata_size_padded); } else if (data_size==0 && rodata_size!=0) { CopyMem((VOID*)(UINTN)(*loader_setting)->rodata_addr_phys,vyx_file->content+sizeof(bp_vyx_VYX_HEADER)+header->text_size_padded,header->rodata_size_padded); + payload_cur+=(header->rodata_size_padded); } else if (data_size!=0 && rodata_size==0) { CopyMem((VOID*)(UINTN)(*loader_setting)->data_addr_phys,vyx_file->content+sizeof(bp_vyx_VYX_HEADER)+header->text_size_padded,header->data_size_padded); + payload_cur+=(header->data_size_padded); } if (!(keycard_file->file_size_bytes<=keycard_pages*4096)) return EFI_COMPROMISED_DATA; CopyMem((VOID*)(UINTN)(*loader_setting)->keycard_addr_phys,keycard_file->content,keycard_file->file_size_bytes); CopyMem((VOID*)(UINTN)(*loader_setting)->shelter_boot_config_addr_phys,(VOID*)shelter_boot_config,sizeof(bp_vyx_SHELTER_BOOT_CONFIG)); + if (header->payload_count!=0) { + EFI_PHYSICAL_ADDRESS *payloads_addr_phys_array=AllocatePool(sizeof(EFI_PHYSICAL_ADDRESS)*header->payload_count); + if (!payloads_addr_phys_array) return EFI_OUT_OF_RESOURCES; + EFI_PHYSICAL_ADDRESS *payloads_addr_virt_array=AllocatePool(sizeof(EFI_VIRTUAL_ADDRESS)*header->payload_count); + if (!payloads_addr_virt_array) return EFI_OUT_OF_RESOURCES; + UINT32 *payloads_page_count_array=AllocatePool(sizeof(UINT32)*header->payload_count); + if (!payloads_page_count_array) return EFI_OUT_OF_RESOURCES; + UINT8 *payloads_map_flags_array=AllocatePool(sizeof(UINT8)*header->payload_count); + if (!payloads_map_flags_array) return EFI_OUT_OF_RESOURCES; + UINT64 payload_found=0; + bp_vyx_PAYLOAD_HEADER *payload_header=NULL; + while (payload_found!=header->payload_count) { + payload_header=(bp_vyx_PAYLOAD_HEADER*)payload_cur; + for (UINTN y=0;y<8;y++) { + if (payload_header->sig[y]!=payload_sig[y]) { + return EFI_COMPROMISED_DATA; + } + } + if (payload_header->payload_pages_count!=pad_size(payload_header->payload_size_bytes,4096)/4096) return EFI_COMPROMISED_DATA; + BOOLEAN is_executable=FALSE; + if (payload_header->map_flags & BP_VYX_PAYLOAD_EXECUTABLE) is_executable=TRUE; + if (is_executable) { + status=gBS->AllocatePages(AllocateAnyPages,EfiLoaderCode,payload_header->payload_pages_count,&payloads_addr_phys_array[payload_found]); + if (EFI_ERROR(status)) { + FreePool(*loader_setting); + return status; + } + } else { + status=gBS->AllocatePages(AllocateAnyPages,EfiLoaderData,payload_header->payload_pages_count,&payloads_addr_phys_array[payload_found]); + if (EFI_ERROR(status)) { + FreePool(*loader_setting); + return status; + } + } + UINT64 current_offset=(UINT64)(payload_cur+sizeof(bp_vyx_PAYLOAD_HEADER)+payload_header->payload_size_bytes)-(UINT64)(vyx_file->content); + if (current_offset>vyx_file->file_size_bytes) return EFI_BUFFER_TOO_SMALL; + SetMem((VOID*)(UINTN)payloads_addr_phys_array[payload_found],pad_size(payload_header->payload_size_bytes,4096),0x0); + CopyMem((VOID*)(UINTN)payloads_addr_phys_array[payload_found],payload_cur+sizeof(bp_vyx_PAYLOAD_HEADER),payload_header->payload_size_bytes); + payloads_addr_virt_array[payload_found]=payload_header->load_address; + payloads_page_count_array[payload_found]=payload_header->payload_pages_count; + payloads_map_flags_array[payload_found]=payload_header->map_flags; + payload_cur+=(sizeof(bp_vyx_PAYLOAD_HEADER)+payload_header->payload_size_bytes); + payload_found++; + } + (*loader_setting)->payloads_addr_phys_array=payloads_addr_phys_array; + (*loader_setting)->payloads_addr_virt_array=payloads_addr_virt_array; + (*loader_setting)->payloads_page_count_array=payloads_page_count_array; + (*loader_setting)->payloads_map_flags_array=payloads_map_flags_array; + (*loader_setting)->payload_count=payload_found; + } else { + (*loader_setting)->payloads_addr_phys_array=NULL; + (*loader_setting)->payloads_addr_virt_array=NULL; + (*loader_setting)->payloads_page_count_array=NULL; + (*loader_setting)->payloads_map_flags_array=NULL; + (*loader_setting)->payload_count=0; + } return EFI_SUCCESS; } EFI_STATUS map_page(UINT64* pml4,UINT64 va,UINT64 pa,UINT64 flags) { @@ -220,6 +286,23 @@ EFI_STATUS map_page(UINT64* pml4,UINT64 va,UINT64 pa,UINT64 flags) { pt[pt_i]=(pa & ~0xFFF) | flags | PAGE_PRESENT; return EFI_SUCCESS; } +BOOLEAN is_page_mapped(UINT64 *pml4,UINT64 va){ + UINT64 pml4_i=(va>>39)&0x1FF; + UINT64 pdpt_i=(va>>30)&0x1FF; + UINT64 pd_i=(va>>21)&0x1FF; + UINT64 pt_i=(va>>12)&0x1FF; + UINT64 *pdpt; + UINT64 *pd; + UINT64 *pt; + if (!(pml4[pml4_i] & PAGE_PRESENT)) return FALSE; + pdpt=(UINT64*)(UINTN)(pml4[pml4_i] & ~0xFFF); + if (!(pdpt[pdpt_i] & PAGE_PRESENT)) return FALSE; + pd=(UINT64*)(UINTN)(pdpt[pdpt_i] & ~0xFFF); + if (!(pd[pd_i] & PAGE_PRESENT)) return FALSE; + pt=(UINT64*)(UINTN)(pd[pd_i] & ~0xFFF); + if (!(pt[pt_i] & PAGE_PRESENT)) return FALSE; + return TRUE; +} EFI_STATUS bp_vyx_create_page_table(bp_vyx_VYX_HEADER *header,bp_vyx_LOADER_SETTING *settings,EFI_PHYSICAL_ADDRESS *page_table_address,EFI_VIRTUAL_ADDRESS *stack_address,EFI_VIRTUAL_ADDRESS *page_table_pool_va) { if (header==NULL || settings==NULL || page_table_address==NULL) { return EFI_INVALID_PARAMETER; @@ -300,6 +383,16 @@ EFI_STATUS bp_vyx_create_page_table(bp_vyx_VYX_HEADER *header,bp_vyx_LOADER_SETT status=map_page(pml4,BP_VYX_SHELTER_LOGGING_RING_BUFFER_VA+i*4096,settings->shelter_logging_ring_buffer_addr_phys+i*4096,PAGE_PRESENT | PAGE_NX | PAGE_RW); if (EFI_ERROR(status)) return status; } + for (UINTN i=0;ipayload_count;i++) { + UINT64 flags=PAGE_PRESENT; + if (!(settings->payloads_map_flags_array[i] & BP_VYX_PAYLOAD_EXECUTABLE)) flags|=PAGE_NX; + if (settings->payloads_map_flags_array[i] & BP_VYX_PAYLOAD_WRITABLE) flags|=PAGE_RW; + for (UINTN y=0;ypayloads_page_count_array[i];y++) { + if (is_page_mapped(pml4,settings->payloads_addr_virt_array[i]+y*4096)) return EFI_OUT_OF_RESOURCES; + status=map_page(pml4,settings->payloads_addr_virt_array[i]+y*4096,settings->payloads_addr_phys_array[i]+y*4096,flags); + if (EFI_ERROR(status)) return status; + } + } *page_table_address=settings->shelter_page_table_addr_phys; return EFI_SUCCESS; } diff --git a/Blastproof/src/main.c b/Blastproof/src/main.c index a7d25e4..c7b18bd 100644 --- a/Blastproof/src/main.c +++ b/Blastproof/src/main.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MPL-2.0 #include #include #include @@ -7,10 +8,9 @@ #include #include #include -#include #include +#include #include "libs/include/debug.h" -#include "libs/include/cpu.h" #include "libs/include/disk.h" #include "libs/include/console.h" #include "libs/include/conf.h" @@ -20,38 +20,33 @@ #include "libs/include/ui.h" #include "libs/include/initfs.h" #include "libs/include/vyx.h" +#include "libs/include/vftm.h" #include "libs/include/key.h" +#include "common/versions.h" #define ARGON2_NO_THREADS -const CHAR16 blastproof_files_path[]=L"\\EFI\\BlastProofFiles\\"; -const CHAR16 blastproof_sign_path[]=L"\\EFI\\BlastProofSign\\"; +const CHAR16 blastproof_files_path[]=L"\\EFI\\BPFILES\\"; +const CHAR16 blastproof_sign_path[]=L"\\EFI\\BPSIGN\\"; BOOLEAN allow_debugging=FALSE; BOOLEAN allow_erroring=FALSE; EFI_GUID gEfiLoadedImageProtocolGuid=EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID gEfiBlockIoProtocolGuid=EFI_BLOCK_IO_PROTOCOL_GUID; EFI_GUID gEfiFileInfoGuid=EFI_FILE_INFO_ID; EFI_GUID gEfiSerialIoProtocolGuid=EFI_SERIAL_IO_PROTOCOL_GUID; -EFI_GUID gEfiPartitionInfoProtocolGuid=EFI_PARTITION_INFO_PROTOCOL_GUID; -UINT16 binary_version=0x0001; +UINT16 binary_version=VY_COMMON_VERSIONS_BOOTLOADER; EFI_STATUS EFIAPI UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { - gST->ConOut->ClearScreen(gST->ConOut); + bp_console_clear_screen(); + bp_vftm_get_vftm_assets(ImageHandle); + bp_vftm_check_manifest_authenticity(bp_key_pk_root,bp_key_sig_root); + bp_vftm_check_manifest_content(); EFI_SERIAL_IO_PROTOCOL *serial; gBS->LocateProtocol(&gEfiSerialIoProtocolGuid,NULL,(void**)&serial); - Print(L"[BlastBoot] Blastproof v0.1\n"); - Print(L"[BlastBoot] Firmware Vendor: %s\n",gST->FirmwareVendor); - Print(L"[BlastBoot] Firmware Revision: %u (0x%08x)\n",gST->FirmwareRevision,gST->FirmwareRevision); - Print(L"[BlastCPU] --- CPU Info ---\n"); - bp_cpu_CPU_INFO booting_cpu_info; - bp_cpu_fill_cpu_info(&booting_cpu_info); - Print(L"[BlastCPU] CPU Vendor ID: %a\n",booting_cpu_info.vendor); - Print(L"[BlastCPU] Max basic CPUID level: 0x%x\n",booting_cpu_info.max_cpuid_level); - Print(L"[BlastCPU] CPU Family: %u\n[BlastCPU] CPU Model: %u\n[BlastCPU] CPU Stepping: %u\n",booting_cpu_info.display_family,booting_cpu_info.display_model,booting_cpu_info.stepping); - Print(L"[BlastCPU] CPU Feature from Ecx: %s\n",booting_cpu_info.ecx_bin); - Print(L"[BlastCPU] CPU Feature from Edx: %s\n",booting_cpu_info.edx_bin); EFI_STATUS status; + bp_console_set_console_mode(); + bp_console_write_centered(L"Blastproof v0.2",0); bp_console_PASSWORD *password; - status=bp_console_read_password(L"[BlastConsole] Please enter boot password: ",&password,L'*'); + status=bp_console_read_password(L"Please enter boot password:",&password); if (EFI_ERROR(status)) { Print(L"[BlastConsole] Error: an error happened during password typing.\n"); while (TRUE) {}; @@ -129,7 +124,7 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { for (INTN i=0;ifont); - UnicodeSPrint(temp_buffer,256,L"\\EFI\\BlastProofFiles\\%s",boot_conf->font); + UnicodeSPrint(temp_buffer,256,L"\\EFI\\BPFILES\\%s",boot_conf->font); status=bp_disk_open_file(root,temp_buffer,&fbm_font); if (EFI_ERROR(status)) { Print(L"[BlastFont] Error: can't open font.\n"); @@ -388,9 +383,9 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { } bp_debug_write_line(serial,"[BlastDebug] If you can see this message, that mean that you're reading on the serial port or that something has gone horribly wrong in the switch to graphical user interface.",allow_debugging); EFI_PHYSICAL_ADDRESS framebuf_base=gop->Mode->FrameBufferBase; - UINT32 *fb=(UINT32 *)(UINTN)framebuf_base; + UINT32 *fb=(UINT32*)(UINTN)framebuf_base; EFI_FILE_PROTOCOL *bootanim_file; - status=bp_disk_open_file(root,L"\\EFI\\BlastProofFiles\\bootanim.bin",&bootanim_file); + status=bp_disk_open_file(root,L"\\EFI\\BPFILES\\BOOTANIM.BIN",&bootanim_file); if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastUi] Error: can't open boot animation.",allow_erroring); while (TRUE) {}; @@ -451,35 +446,25 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { while (TRUE) {}; } bp_ui_TEXT_BOX *text_box; - status=bp_ui_draw_text_ascii(fb,font_render,-1,(UINTN)info_mode->VerticalResolution*0.9,info_mode->HorizontalResolution,info_mode->VerticalResolution,"Locating Filesystems...",&text_box); + status=bp_ui_draw_text_ascii(fb,font_render,-1,(UINTN)info_mode->VerticalResolution*0.9,info_mode->HorizontalResolution,info_mode->VerticalResolution,"Locating and Loading Filesystems...",&text_box); if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastUi] Error: placing text on framebuffer doesn't work.",allow_erroring); while (TRUE) {}; } - UINTN num_handle; - EFI_HANDLE *handles=NULL; - status=gBS->LocateHandleBuffer(ByProtocol,&gEfiBlockIoProtocolGuid,NULL,&num_handle,&handles); - if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't obtain all handles for BlockIO protocol.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_NO_BLOCKIO_PROTOCOL\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } - AsciiSPrint(temp,sizeof(temp),"[BlastDebug:BlastDisk] Managed to obtain %d handles.",num_handle); - bp_debug_write_line(serial,temp,allow_debugging); BOOLEAN found_initfs=FALSE; BOOLEAN found_signsyst=FALSE; - UINTN initfs_index; - UINTN signsyst_index; - for (UINTN i=0;iHandleProtocol(handles[i],&gEfiBlockIoProtocolGuid,(VOID **)&blockio); - if (EFI_ERROR(status)) continue; - if (!blockio->Media->LogicalPartition) continue; - EFI_PARTITION_INFO_PROTOCOL *part_info; - status=gBS->HandleProtocol(handles[i],&gEfiPartitionInfoProtocolGuid,(VOID **)&part_info); - if (EFI_ERROR(status)) continue; - EFI_GUID efi_type_guid=part_info->Info.Gpt.PartitionTypeGUID; - EFI_GUID efi_unique_guid=part_info->Info.Gpt.UniquePartitionGUID; + bp_vftm_VFTM_ASSETS *assets=bp_vftm_get_assets(); + EFI_PARTITION_ENTRY *part_entry=(EFI_PARTITION_ENTRY*)assets->partition_table_buffer; + UINT8 *initfs_buf=NULL; + UINT8 *signsyst_buf=NULL; + UINTN initfs_size_bytes; + UINTN signsyst_size_bytes; + UINTN initfs_block_count; + UINTN signsyst_block_count; + for (UINTN i=0;ipart_count;i++) { + EFI_PARTITION_ENTRY *current=&part_entry[i]; + EFI_GUID efi_type_guid=current->PartitionTypeGUID; + EFI_GUID efi_unique_guid=current->UniquePartitionGUID; UINT8 type_guid[16]; UINT8 unique_guid[16]; type_guid[0]=(efi_type_guid.Data1>>24)&0xFF; @@ -500,151 +485,115 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { unique_guid[6]=(efi_unique_guid.Data3>>8)&0xFF; unique_guid[7]=efi_unique_guid.Data3&0xFF; CopyMem(unique_guid+8,efi_unique_guid.Data4,8); - if (CompareMem(type_guid,boot_conf->initfs_partition_type_guid,16)==0 && CompareMem(unique_guid,boot_conf->initfs_partition_guid,16)==0 && StrCmp(part_info->Info.Gpt.PartitionName,L"InitFS")==0) { - if (part_info->Info.Gpt.EndingLBA-part_info->Info.Gpt.StartingLBA<=0) { + if (CompareMem(type_guid,boot_conf->initfs_partition_type_guid,16)==0 && CompareMem(unique_guid,boot_conf->initfs_partition_guid,16)==0 && StrCmp(current->PartitionName,L"InitFS")==0) { + if (current->EndingLBA-current->StartingLBA<=0) { bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: found too small InitFS.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_TOO_SMALL\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - if (handles) FreePool(handles); while (TRUE) {}; } - found_initfs=TRUE; - initfs_index=i; - } else if (CompareMem(type_guid,boot_conf->signsyst_partition_type_guid,16)==0 && CompareMem(unique_guid,boot_conf->signsyst_partition_guid,16)==0 && StrCmp(part_info->Info.Gpt.PartitionName,L"SignSyst")==0) { - if (part_info->Info.Gpt.EndingLBA-part_info->Info.Gpt.StartingLBA<=0) { + if (!found_initfs) { + found_initfs=TRUE; + initfs_block_count=current->EndingLBA-current->StartingLBA+1; + initfs_size_bytes=(initfs_block_count)*assets->block_io_disk->Media->BlockSize; + UINTN initfs_page_count=(initfs_size_bytes+EFI_PAGE_SIZE-1)/EFI_PAGE_SIZE; + EFI_PHYSICAL_ADDRESS initfs_ptr; + status=gBS->AllocatePages(AllocateAnyPages,EfiLoaderData,initfs_page_count,&initfs_ptr); + if (EFI_ERROR(status)) { + bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't allocate memory for InitFS.",allow_erroring); + bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_NO_MEMORY\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); + while (TRUE) {}; + } + status=assets->block_io_disk->ReadBlocks(assets->block_io_disk,assets->block_io_disk->Media->MediaId,current->StartingLBA,initfs_size_bytes,(VOID*)initfs_ptr); + if (EFI_ERROR(status)) { + bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't read InitFS from disk.",allow_erroring); + bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_NO_READ\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); + while (TRUE) {}; + } + initfs_buf=(UINT8*)initfs_ptr; + } + } else if (CompareMem(type_guid,boot_conf->signsyst_partition_type_guid,16)==0 && CompareMem(unique_guid,boot_conf->signsyst_partition_guid,16)==0 && StrCmp(current->PartitionName,L"SignSyst")==0) { + if (current->EndingLBA-current->StartingLBA<=0) { bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: found too small SignSyst.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_TOO_SMALL\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - if (handles) FreePool(handles); while (TRUE) {}; } - found_signsyst=TRUE; - signsyst_index=i; + if (!found_signsyst) { + found_signsyst=TRUE; + signsyst_block_count=current->EndingLBA-current->StartingLBA+1; + signsyst_size_bytes=(signsyst_block_count)*assets->block_io_disk->Media->BlockSize; + UINTN signsyst_page_count=(signsyst_size_bytes+EFI_PAGE_SIZE-1)/EFI_PAGE_SIZE; + EFI_PHYSICAL_ADDRESS signsyst_ptr; + status=gBS->AllocatePages(AllocateAnyPages,EfiLoaderData,signsyst_page_count,&signsyst_ptr); + if (EFI_ERROR(status)) { + bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't allocate memory for SignSyst.",allow_erroring); + bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_NO_MEMORY\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); + while (TRUE) {}; + } + status=assets->block_io_disk->ReadBlocks(assets->block_io_disk,assets->block_io_disk->Media->MediaId,current->StartingLBA,signsyst_size_bytes,(VOID*)signsyst_ptr); + if (EFI_ERROR(status)) { + bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't read SignSyst from disk.",allow_erroring); + bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_NO_READ\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); + while (TRUE) {}; + } + signsyst_buf=(UINT8*)signsyst_ptr; + } } } if (!found_initfs && !found_signsyst) { bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: couldn't found InitFS and SignSyst.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_VYSTEM_FS_NOT_FOUND\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - if (handles) FreePool(handles); while (TRUE) {}; } else if (!found_initfs) { bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: couldn't found InitFS.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_NOT_FOUND\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - if (handles) FreePool(handles); while (TRUE) {}; } else if (!found_signsyst) { bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: couldn't found SignSyst.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_NOT_FOUND\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - if (handles) FreePool(handles); while (TRUE) {}; } bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Found InitFS and SignSyst.",allow_debugging); bp_ui_erase_text(fb,info_mode->HorizontalResolution,info_mode->VerticalResolution,text_box); - status=bp_ui_draw_text_ascii(fb,font_render,-1,(UINTN)info_mode->VerticalResolution*0.9,info_mode->HorizontalResolution,info_mode->VerticalResolution,"Loading Filesystems Headers...",&text_box); - EFI_BLOCK_IO_PROTOCOL *initfs_blockio; - status=gBS->HandleProtocol(handles[initfs_index],&gEfiBlockIoProtocolGuid,(VOID **)&initfs_blockio); - if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't get InitFS BlockIO protocol.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_NO_BLOCK_IO\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - if (handles) FreePool(handles); - while (TRUE) {}; - } - EFI_BLOCK_IO_PROTOCOL *signsyst_blockio; - status=gBS->HandleProtocol(handles[signsyst_index],&gEfiBlockIoProtocolGuid,(VOID **)&signsyst_blockio); - if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't get SignSyst BlockIO protocol.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_NO_BLOCK_IO\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - if (handles) FreePool(handles); - while (TRUE) {}; - } - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Obtained both BlockIO protocol.",allow_debugging); - UINTN initfs_block_size=initfs_blockio->Media->BlockSize; - UINT8 *initfs_first_lba=AllocatePool(initfs_block_size); - if (!initfs_first_lba) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: allocating memory for InitFS first LBA failed.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_FIRST_LBA_NO_MEMORY\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } - if (!initfs_blockio->Media->MediaPresent) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: InitFS mysteriously disappeared.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_NOT_HERE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); - while (TRUE) {}; - } - status=initfs_blockio->ReadBlocks(initfs_blockio,initfs_blockio->Media->MediaId,0,initfs_block_size,initfs_first_lba); - if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't read InitFS first LBA.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_FIRST_LBA_NO_READ\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); - while (TRUE) {}; - } - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Readed first LBA for InitFS.",allow_debugging); - UINTN signsyst_block_size=signsyst_blockio->Media->BlockSize; - UINT8 *signsyst_first_lba=AllocatePool(signsyst_block_size); - if (!signsyst_first_lba) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: allocating memory for SignSyst first LBA failed.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_FIRST_LBA_NO_MEMORY\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } - if (!signsyst_blockio->Media->MediaPresent) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: SignSyst mysteriously disappeared.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_NOT_HERE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(signsyst_first_lba); - while (TRUE) {}; - } - status=signsyst_blockio->ReadBlocks(signsyst_blockio,signsyst_blockio->Media->MediaId,0,signsyst_block_size,signsyst_first_lba); - if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Error: can't read SignSyst first LBA.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_FIRST_LBA_NO_READ\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(signsyst_first_lba); - while (TRUE) {}; - } - bp_debug_write_line(serial,"[BlastDebug:BlastDisk] Readed first LBA for SignSyst.",allow_debugging); - bp_ui_erase_text(fb,info_mode->HorizontalResolution,info_mode->VerticalResolution,text_box); status=bp_ui_draw_text_ascii(fb,font_render,-1,(UINTN)info_mode->VerticalResolution*0.9,info_mode->HorizontalResolution,info_mode->VerticalResolution,"Parsing Filesystems Headers...",&text_box); bp_initfs_INITFS_HEADER *initfs_header=NULL; - status=bp_initfs_parse_initfs_header(initfs_first_lba,initfs_block_size,&initfs_header); + status=bp_initfs_parse_initfs_header(initfs_buf,512,&initfs_header); if (status==EFI_UNSUPPORTED) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: provided InitFS isn't compatible with InitFS driver.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_WRONG_VERSION\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); while (TRUE) {}; } else if (status==EFI_COMPROMISED_DATA) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: provided InitFS doesn't have the InitFS signature.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_WRONG_SIGNATURE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); while (TRUE) {}; } else if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: can't read InitFS header.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_HEADER_READ_ERROR\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); while (TRUE) {}; } bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Parsed InitFS header.",allow_debugging); - AsciiSPrint(temp,sizeof(temp),"[BlastDebug:BlastInitFS] Bootloader version: 0x%04x; InitFS version: 0x%04x; OS version: 0x%08x",initfs_header->bootloader_version,initfs_header->bootloader_version,initfs_header->os_version); + AsciiSPrint(temp,sizeof(temp),"[BlastDebug:BlastInitFS] Bootloader version: 0x%04x; InitFS version: 0x%04x; OS version: 0x%08x",initfs_header->bootloader_version,initfs_header->initfs_version,initfs_header->os_version); bp_debug_write_line(serial,temp,allow_debugging); AsciiSPrint(temp,sizeof(temp),"[BlastDebug:BlastInitFS] InitFS Size: %d bytes; Table size: %d bytes; Files area size: %d bytes",initfs_header->initfs_size,initfs_header->table_size,initfs_header->files_area_size); bp_debug_write_line(serial,temp,allow_debugging); AsciiSPrint(temp,sizeof(temp),"[BlastDebug:BlastInitFS] Entry width: %d bytes; Entries count: %d; Files area offset: %d bytes",initfs_header->entries_width,initfs_header->entries_count,initfs_header->files_area_offset); bp_debug_write_line(serial,temp,allow_debugging); bp_initfs_SIGNSYST_HEADER *signsyst_header=NULL; - status=bp_initfs_parse_signsyst_header(signsyst_first_lba,signsyst_block_size,&signsyst_header); + status=bp_initfs_parse_signsyst_header(signsyst_buf,512,&signsyst_header); if (status==EFI_UNSUPPORTED) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: provided SignSyst isn't compatible with InitFS driver.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_WRONG_VERSION\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(signsyst_first_lba); while (TRUE) {}; } else if (status==EFI_COMPROMISED_DATA) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: provided SignSyst doesn't have the SignSyst signature.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_WRONG_SIGNATURE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(signsyst_first_lba); while (TRUE) {}; } else if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: can't read SignSyst header.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_HEADER_READ_ERROR\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(signsyst_first_lba); while (TRUE) {}; } bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Parsed SignSyst header.",allow_debugging); - AsciiSPrint(temp,sizeof(temp),"[BlastDebug:BlastInitFS] Bootloader version: 0x%04x; InitFS version: 0x%04x; OS version: 0x%08x",signsyst_header->bootloader_version,signsyst_header->bootloader_version,signsyst_header->os_version); + AsciiSPrint(temp,sizeof(temp),"[BlastDebug:BlastInitFS] Bootloader version: 0x%04x; InitFS version: 0x%04x; OS version: 0x%08x",signsyst_header->bootloader_version,signsyst_header->initfs_version,signsyst_header->os_version); bp_debug_write_line(serial,temp,allow_debugging); AsciiSPrint(temp,sizeof(temp),"[BlastDebug:BlastInitFS] Signature size: %d bytes; Signature count: %d",signsyst_header->signature_size,signsyst_header->signature_count); bp_debug_write_line(serial,temp,allow_debugging); @@ -657,12 +606,10 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: critical security violation in boot process:",allow_erroring); bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] InitFS header isn't valid.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_HEADER_NOT_VALID\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); while (TRUE) {}; } else if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: InitFS header couldn't be verified.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_HEADER_NOT_VERIFIABLE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); while (TRUE) {}; } bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Successfully verified InitFS header.",allow_debugging); @@ -671,12 +618,10 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: critical security violation in boot process:",allow_erroring); bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] SignSyst header isn't valid.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_HEADER_NOT_VALID\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(signsyst_first_lba); while (TRUE) {}; } else if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: SignSyst header couldn't be verified.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_HEADER_NOT_VERIFIABLE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(signsyst_first_lba); while (TRUE) {}; } bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Successfully verified SignSyst header.",allow_debugging); @@ -685,79 +630,27 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: critical security violation in boot process:",allow_erroring); bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Provided InitFS and SignSyst doesn't match.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_FS_NO_MATCH\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); - FreePool(signsyst_first_lba); while (TRUE) {}; } else if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: can't verified that provided filesystems match.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_FS_NOT_MATCHABLE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - FreePool(initfs_first_lba); - FreePool(signsyst_first_lba); while (TRUE) {}; } bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Both filesystems match.",allow_debugging); - UINTN initfs_block_count=initfs_blockio->Media->LastBlock+1; - UINTN initfs_size_bytes=initfs_block_count*initfs_block_size; if (initfs_header->initfs_size>initfs_size_bytes) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: InitFS size provided in header is bigger than partition size.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_SIZE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); while (TRUE) {}; } - UINTN signsyst_block_count=signsyst_blockio->Media->LastBlock+1; - UINTN signsyst_size_bytes=signsyst_block_count*signsyst_block_size; if (signsyst_header->signsyst_size>signsyst_size_bytes) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: SignSyst size provided in header is bigger than partition size.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_SIZE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); while (TRUE) {}; } bp_ui_erase_text(fb,info_mode->HorizontalResolution,info_mode->VerticalResolution,text_box); - status=bp_ui_draw_text_ascii(fb,font_render,-1,(UINTN)info_mode->VerticalResolution*0.9,info_mode->HorizontalResolution,info_mode->VerticalResolution,"Loading Filesystems...",&text_box); - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Allocating memory for InitFS...",allow_debugging); - UINTN initfs_page_count=(initfs_size_bytes+EFI_PAGE_SIZE-1)/EFI_PAGE_SIZE; - EFI_PHYSICAL_ADDRESS initfs_ptr; - status=gBS->AllocatePages(AllocateAnyPages,EfiLoaderData,initfs_page_count,&initfs_ptr); - if (status==EFI_OUT_OF_RESOURCES) { - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: InitFS couldn't be loaded because the system doesn't have enough memory.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_NO_MEMORY\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } else if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: InitFS couldn't be loaded because of a page allocation error.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_MEMORY\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Loading InitFS from disk...",allow_debugging); - status=initfs_blockio->ReadBlocks(initfs_blockio,initfs_blockio->Media->MediaId,0,initfs_size_bytes,(VOID *)initfs_ptr); - if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: InitFS couldn't be loaded.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_LOAD_ERROR\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Successfully loaded InitFS.",allow_debugging); - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Allocating memory for SignSyst...",allow_debugging); - UINTN signsyst_page_count=(signsyst_size_bytes+EFI_PAGE_SIZE-1)/EFI_PAGE_SIZE; - EFI_PHYSICAL_ADDRESS signsyst_ptr; - status=gBS->AllocatePages(AllocateAnyPages,EfiLoaderData,signsyst_page_count,&signsyst_ptr); - if (status==EFI_OUT_OF_RESOURCES) { - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: SignSyst couldn't be loaded because the system doesn't have enough memory.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_NO_MEMORY\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } else if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: SignSyst couldn't be loaded because of a page allocation error.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_MEMORY\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Loading SignSyst from disk...",allow_debugging); - status=initfs_blockio->ReadBlocks(signsyst_blockio,signsyst_blockio->Media->MediaId,0,signsyst_size_bytes,(VOID *)signsyst_ptr); - if (EFI_ERROR(status)) { - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: SignSyst couldn't be loaded.",allow_erroring); - bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_LOAD_ERROR\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); - while (TRUE) {}; - } - bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Successfully loaded SignSyst.",allow_debugging); - bp_ui_erase_text(fb,info_mode->HorizontalResolution,info_mode->VerticalResolution,text_box); status=bp_ui_draw_text_ascii(fb,font_render,-1,(UINTN)info_mode->VerticalResolution*0.9,info_mode->HorizontalResolution,info_mode->VerticalResolution,"Parsing Filesystems...",&text_box); bp_initfs_INITFS *initfs=NULL; - status=bp_initfs_create_initfs_structure(initfs_header,(UINT8 *)initfs_ptr,&initfs); + status=bp_initfs_create_initfs_structure(initfs_header,initfs_buf,&initfs); if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: can't parse InitFS structure.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_INITFS_NO_STRUCTURE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); @@ -765,7 +658,7 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { } bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Successfully parsed InitFS structure.",allow_debugging); bp_initfs_SIGNSYST *signsyst=NULL; - status=bp_initfs_create_signsyst_structure(signsyst_header,(UINT8 *)signsyst_ptr,&signsyst); + status=bp_initfs_create_signsyst_structure(signsyst_header,signsyst_buf,&signsyst); if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastInitFS] Error: can't parse SignSyst structure.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_SIGNSYST_NO_STRUCTURE\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); @@ -816,6 +709,25 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { while (TRUE) {}; } bp_debug_write_line(serial,"[BlastDebug:BlastVyx] Successfully obtained kernel header.",allow_debugging); + void *rsdp=NULL; + UINT8 acpi_ver=0; + for (UINTN i=0;iNumberOfTableEntries;i++) { + EFI_CONFIGURATION_TABLE *t=&SystemTable->ConfigurationTable[i]; + if (CompareGuid(&t->VendorGuid,&gEfiAcpi20TableGuid)) { + rsdp=t->VendorTable; + acpi_ver=2; + break; + } + if (CompareGuid(&t->VendorGuid,&gEfiAcpi10TableGuid)) { + acpi_ver=1; + rsdp=t->VendorTable; + } + } + if (acpi_ver==0) { + bp_debug_write_line(serial,"[BlastDebug:BlastVyx] Error: can't obtain ACPI RSDP.",allow_erroring); + bp_ui_show_error_screen(serial,"BP_ERROR_NO_ACPI_FOUND\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); + while (TRUE) {}; + } bp_vyx_SHELTER_BOOT_CONFIG *kernel_config=AllocatePool(sizeof(bp_vyx_SHELTER_BOOT_CONFIG)); status=bp_vyx_create_shelter_boot_conf(boot_conf->kernel_log_level, boot_conf->kernel_test_benchmark, @@ -823,12 +735,27 @@ UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable) { boot_conf->kernel_log_disable_serial_port, boot_conf->kernel_disable_serial_port, boot_conf->kernel_log_ring_size, + (UINT64)rsdp, + acpi_ver, + boot_conf->kernel_kbd_events_queue_capacity, kernel_config); if (EFI_ERROR(status)) { bp_debug_write_line(serial,"[BlastDebug:BlastVyx] Error: can't create kernel config.",allow_erroring); bp_ui_show_error_screen(serial,"BP_ERROR_KERNEL_NO_CONFIG\0",fb,font_render,info_mode->HorizontalResolution,info_mode->VerticalResolution,error_frame,allow_erroring); while (TRUE) {}; } + bp_vyx_SHELTER_FB_CONFIG *fb_conf=&kernel_config->fb_config; + fb_conf->fb_present=TRUE; + fb_conf->fb_pa=(UINT64)fb; + fb_conf->white_pixel_value=bp_graphic_get_pixel_by_color(&(bp_graphic_COLOR_RGB){.r=0xFF,.g=0xFF,.b=0xFF},settings.red_bits,settings.green_bits,settings.blue_bits); + fb_conf->gray_pixel_value=bp_graphic_get_pixel_by_color(&(bp_graphic_COLOR_RGB){.r=0x30,.g=0x30,.b=0x30},settings.red_bits,settings.green_bits,settings.blue_bits); + fb_conf->size_in_bytes=info_mode->HorizontalResolution*info_mode->VerticalResolution*sizeof(UINT32); + fb_conf->fb_height=info_mode->VerticalResolution; + fb_conf->fb_width=info_mode->HorizontalResolution; + fb_conf->text_x=text_box->x; + fb_conf->text_y=text_box->y; + fb_conf->text_width=text_box->width; + fb_conf->text_height=text_box->height; bp_debug_write_line(serial,"[BlastDebug:BlastVyx] Successfully created kernel config.",allow_debugging); bp_vyx_LOADER_SETTING *loader_settings=NULL; status=bp_vyx_setup_physical_pages(kernel_header,kernel_file,keycard_file,kernel_config,&loader_settings); diff --git a/Blastproof/src/main.inf b/Blastproof/src/main.inf index b61190c..42da299 100644 --- a/Blastproof/src/main.inf +++ b/Blastproof/src/main.inf @@ -3,13 +3,12 @@ BASE_NAME = BlastMain FILE_GUID = e7a0b308-aebb-11f0-9ba9-10ffe08423a6 MODULE_TYPE = UEFI_APPLICATION - VERSION_STRING = 0.1 + VERSION_STRING = 0.2 ENTRY_POINT = UefiMain DEFINEs = ARGON2_NO_THREADS [Sources] main.c - libs/src/cpu.c libs/src/disk.c libs/src/console.c libs/src/conf.c @@ -20,6 +19,8 @@ libs/src/ui.c libs/src/initfs.c libs/src/vyx.c + libs/src/layout.c + libs/src/vftm.c libs/sha3/sha3.c libs/argon2/argon2.c libs/argon2/blake2b.c @@ -47,3 +48,6 @@ [Packages] MdePkg/MdePkg.dec + +[Guids] + gEfiPartTypeSystemPartGuid diff --git a/build.json b/build.json new file mode 100644 index 0000000..20d6851 --- /dev/null +++ b/build.json @@ -0,0 +1,152 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"root", + "name":"Vystem build", + "global_uuid":[ + "INITFS_UNIQUE_UUID", + "SIGNSYST_UNIQUE_UUID", + "DISK_GUID", + "ESP_PARTITION_UNIQUE_GUID" + ], + "global_vars":{ + "__VYBUILD_COMPILER_HASH_DUMP_MACHINE":"gcc -dumpmachine", + "__VYBUILD_COMPILER_HASH_DUMP_SPECS":"gcc -dumpspecs", + "__VYBUILD_COMPILER_HASH_SYSROOT":"gcc -print-sysroot", + "comment1":"HEY YOU, YES YOU ! if you modify the VYSTEM_KEYGEN_PASSWORD variable, it will automatically setup", + "comment2":"the boot password with whatever is VYSTEM_KEYGEN_PASSWORD. Do NOT use it if you want to manually enter", + "comment3":"your boot password into keygen. You have been warned.", + "VYSTEM_KEYGEN_PASSWORD":"test", + "INITFS_DIR":"initfs_dir", + "EDK2_DIR":"edk2", + "EDK2_BLASTPROOF_DIR":"edk2/Blastproof", + "PYTHON_EXE":"python", + "ASSEMBLER":"nasm", + "C_COMPILER":"gcc", + "CPP_COMPILER":"g++", + "ASM_OUTPUT_FORMAT":"bin", + "LINKER":"ld", + "KEYCARD_BINARY_NAME":"keycard.bin", + "SHELTER_COMPILATION_FLAGS":"-fno-stack-protector -O1 -Wall -Wextra -Werror -Wpedantic -Wshadow -Wconversion -Wsign-conversion -Wstrict-prototypes -Wmissing-prototypes -Wundef -fmax-errors=0 -Ilib/include/", + "SHELTER_BINARY_NAME":"shelter.vyx", + "BOOTANIM_BINARY_NAME":"bootanim", + "FONTGEN_BINARY_NAME":"fontgen", + "BOOTANIM_HEIGH":"1080", + "BOOTANIM_WIDTH":"1920", + "ESP_PARTITION_TYPE_GUID":"C12A7328-F81F-11D2-BA4B-00A0C93EC93B", + "INITFS_PARTITION_TYPE_GUID":"8362b434-d825-11f0-a68f-10ffe08423a6", + "SIGNSYST_PARTITION_TYPE_GUID":"da0048b4-d826-11f0-b877-10ffe08423a6" + }, + "actions":[ + { + "action":"ensure_folder_existence", + "args":{ + "path_variables":true, + "path":"%rootcallerfolder%/$INITFS_DIR$" + } + }, + { + "action":"run_submodule", + "args":{ + "file_variables":false, + "file":"shelter/shelter.json", + "wait":true, + "block_if_fail":true + } + }, + { + "action":"run_submodule", + "args":{ + "file_variables":false, + "file":"Blastproof/bootloader.json", + "wait":true, + "block_if_fail":true + } + }, + { + "action":"run_submodule", + "args":{ + "file_variables":false, + "file":"esp.json", + "wait":true, + "block_if_fail":true + } + }, + { + "action":"run_submodule", + "args":{ + "file_variables":false, + "file":"disk.json", + "wait":true, + "block_if_fail":true + } + }, + { + "action":"run_actions_if", + "args":{ + "condition":{ + "condition_variables":false, + "condition":"var_not_exists", + "condition_args_variables":false, + "condition_args":[ + "%1%" + ] + }, + "actions":[ + { + "action":"run_command_str_wait", + "args":{ + "command_variables":true, + "command":"qemu-system-x86_64 -machine q35 -smp cores=4,threads=1,sockets=1 -drive if=pflash,format=raw,unit=0,readonly=on,file=edk2/Build/OvmfX64/RELEASE_GCC/FV/OVMF_CODE.fd -drive if=pflash,format=raw,file=edk2/Build/OvmfX64/RELEASE_GCC/FV/OVMF_VARS.fd -drive file=edk2/disk.bin,format=raw,if=virtio,index=0 -serial stdio -m 4096M -cpu host,+x2apic -accel kvm", + "success_status":[ + 0 + ], + "ignore_success_status":false, + "show_output":"live" + } + }, + { + "action":"exit_current_module", + "args":{ + "is_fail":false + } + } + ] + } + }, + { + "action":"run_actions_if", + "args":{ + "condition":{ + "condition_variables":false, + "condition":"var_equals", + "condition_args_variables":false, + "condition_args":[ + "%1%", + "img" + ] + }, + "actions":[ + { + "action":"run_command_str_wait", + "args":{ + "command_variables":true, + "command":"echo \"Disk image saved under edk2/disk.bin\"", + "success_status":[ + 0 + ], + "ignore_success_status":false, + "show_output":"live" + } + }, + { + "action":"exit_current_module", + "args":{ + "is_fail":false + } + } + ] + } + } + ] +} diff --git a/build.sh b/build.sh deleted file mode 100755 index f4280a5..0000000 --- a/build.sh +++ /dev/null @@ -1,355 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -set -e -run() { - local cmd="$1" - local success_msg="$2" - local error_msg="$3" - shift 3 - tmpfile=$(mktemp) - if eval "$cmd" >"$tmpfile" 2>&1; then - echo "${success_msg:-[OK] Command succeeded}" - rm -f "$tmpfile" - return 0 - else - echo -e "${error_msg:-[ERR] Command failed]}" - cat "$tmpfile" - rm -f "$tmpfile" - return 1 - fi -} - -rm -rf initfs_dir -mkdir -p initfs_dir - -echo "[Build] Checking virtual memory layout:" -echo "" -python3 shelter/tools/checker/vmem_layout_check.py shelter/lib/include/memory/vmem_layout.h -echo "" - -mkdir -p shelter/lib/include/kernel/tests/payloads - -echo "[Build] Generating kernel payloads:" -echo -n "[Build] Radix tests..." -run "python shelter/tools/generator/radix_tree_payload_gen.py > shelter/lib/include/kernel/tests/payloads/test_radix_payload.h" " done." "\n[Build] Error:\n" -echo -n "[Build] Pez tests..." -run "python shelter/tools/generator/pez_alloc_free_payload_gen.py > shelter/lib/include/kernel/tests/payloads/test_pez_payload.h" " done." "\n[Build] Error:\n" -echo -n "[Build] Malloc tests..." -run "python shelter/tools/generator/malloc_payload_gen.py > shelter/lib/include/kernel/tests/payloads/test_malloc_payload.h" " done." "\n[Build] Error:\n" -echo "[Build] Successfully generated kernel payloads." - -echo "[Build] Compiling keycard:" -echo -n "[Build] Changing directory..." -run "cd Blastproof/src" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up..." -run "rm -f ./keycard.bin" " done." "\n[Build] Error:\n" -echo -n "[Build] Compiling keycard executable..." -run "nasm -f bin keycard.asm -o keycard.bin" " done." "\n[Build] Error:\n" -echo -n "[Build] Moving keycard to InitFS..." -run "mv keycard.bin ../../initfs_dir/" " done." "\n[Build] Error:\n" -echo -n "[Build] Exiting directory..." -run "cd ../.." " done." "\n[Build] Error:\n" -echo "[Build] Successfully compiled keycard." - -echo "[Build] Compiling vyld and Shelter:" -echo -n "[Build] Changing directory..." -run "cd vyld" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up..." -run "rm -f ./vyld" " done." "\n[Build] Error:\n" -echo -n "[Build] Compiling vyld executable..." -run "g++ vyld.cpp -o vyld" " done." "\n[Build] Error:\n" -echo -n "[Build] Granting permissions to execute vyld..." -run "chmod +x ./vyld" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up..." -run "rm -f *.o *.vyx *.elf *.bin" " done." "\n[Build] Error:\n" -echo -n "[Build] Changing directory..." -run "cd ../shelter" " done." "\n[Build] Error:\n" -echo "[Build] Compiling Shelter:" -echo "" -VYLD_COMPILATION_FLAGS="-fno-stack-protector -O1 -Wall -Wextra -Werror -Wpedantic -Wshadow -Wconversion -Wsign-conversion -Wstrict-prototypes -Wmissing-prototypes -Wundef -fmax-errors=0 -Ilib/include/" \ - ../vyld/vyld main.c \ - lib/src/kernel/log.c \ - lib/src/kernel/conf.c \ - lib/src/kernel/tests/test_utils.c \ - lib/src/kernel/tests/test_slabs.c \ - lib/src/kernel/tests/test_radix.c \ - lib/src/kernel/tests/test_pez.c \ - lib/src/kernel/tests/test_malloc.c \ - lib/src/std/mem.c \ - lib/src/std/malloc.c \ - lib/src/cpu/tsc.c \ - lib/src/cpu/serial.c \ - lib/src/memory/page.c \ - lib/src/memory/ring.c \ - lib/src/memory/pba.c \ - lib/src/memory/heap.c \ - lib/src/memory/slabs/slab_reg_phys.c \ - lib/src/memory/slabs/slab_reg_virt.c \ - lib/src/memory/slabs/slab_radix_node.c \ - lib/src/memory/slabs/slab_generic.c \ - lib/src/memory/pez/pez.c \ - lib/src/memory/pez/pez_debug.c \ - lib/src/memory/pez/radix.c \ - shelter.vyx -echo "" -echo -n "[Build] Copying Shelter executable.." -run "mv shelter.vyx ../initfs_dir/" " done." "\n[Build] Error:\n" -echo -n "[Build] Exiting directory..." -run "cd .." " done." "\n[Build] Error:\n" -echo "[Build] Successfully compiled all files." - -if [ ! -d "edk2" ]; then - echo "[Build] Cloning and setuping edk2:" - echo "[Build] Cloning edk2:" - git clone https://github.com/tianocore/edk2.git - echo -n "[Build] Entering directory..." - run "cd edk2" " done." "\n[Build] Error:\n" - echo "[Build] Cloning submodule:" - git submodule update --init --recursive --progress - echo "[Build] Compiling necessary tools:" - make -C BaseTools/ - tmpfile=$(mktemp) - echo -n "[Build] Setuping environment..." - . ./edksetup.sh >"$tmpfile" 2>&1 - status=$? - if [[ $status -eq 0 ]]; then - echo " done." - else - echo -e "\n[Build] Error:\n$(cat "$tmpfile")" - exit $status - fi - rm -f "$tmpfile" - echo -n "[Build] Building OVMF..." - run "build -p OvmfPkg/OvmfPkgX64.dsc -b RELEASE -a X64 -t GCC" " done." "\n[Build] Error:\n" - echo -n "[Build] Exiting directory..." - run "cd .." " done." "\n[Build] Error:\n" - echo "[Build] Succesfully setuped edk2." -fi - -cd edk2 -tmpfile=$(mktemp) -echo -n "[Build] Setuping environment..." -. ./edksetup.sh >"$tmpfile" 2>&1 -status=$? -if [[ $status -eq 0 ]]; then - echo " done." -else - echo -e "\n[Build] Error:\n$(cat "$tmpfile")" - exit $status -fi -rm -f "$tmpfile" -cd .. - -echo -n "[Build] Copying Blastproof files..." -cp ./Blastproof ./edk2/ -r -echo " done." -echo -n "[Build] Entering directory..." -cd edk2 -echo " done." - -echo "[Build] Building bootanim executable:" -echo -n "[Build] Changing directory..." -run "cd Blastproof/bootanim" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up..." -run "rm bootanim bootanim.bin -f" " done." "\n[Build] Error:\n" -echo -n "[Build] Compiling bootanim..." -run "g++ bootanim.cpp -o bootanim -Ofast -march=native" " done." "\n[Build] Error:\n" -echo -n "[Build] Giving permissions to execute bootanim..." -run "chmod +x bootanim" " done." "\n[Build] Error:\n" -echo "[Build] Bootanim executable built." - -echo "[Build] Building boot animation:" -echo -n "[Build] Generating boot animation... " -run "./bootanim logo.png file 1920 1080" " done." "\n[Build] Error:\n" -echo -n "[Build] Exiting directory... " -run "cd ../.." " done." "\n[Build] Error:\n" -echo "[Build] Boot animation built." - -echo "[Build] Building fontgen executable:" -echo -n "[Build] Changing directory..." -run "cd Blastproof/fontgen" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up..." -run "rm fontgen bitra-ascii-medium.fbm -f" " done." "\n[Build] Error:\n" -echo -n "[Build] Compiling fontgen..." -run "g++ fontgen.cpp -o fontgen" " done." "\n[Build] Error:\n" -echo -n "[Build] Giving permissions to execute fontgen..." -run "chmod +x fontgen" " done." "\n[Build] Error:\n" -echo "[Build] Fontgen executable built." - -echo "[Build] Building Bitra font:" -echo -n "[Build] Running fontgen..." -run "./fontgen \"#FFFFFF\" \"#000000\" ascii ./chars" " done." "\n[Build] Error:\n" -echo -n "[Build] Renaming generated font..." -run "mv font.fbm bitra-ascii-medium.fbm" " done." "\n[Build] Error:\n" -echo -n "[Build] Exiting directory..." -run "cd ../.." " done." "\n[Build] Error:\n" -echo "[Build] Bitra font built." - -echo "[Build] Building initfsgen executable:" -echo -n "[Build] Changing directory..." -run "cd Blastproof/initfsgen" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up..." -run "rm -f initfsgen" " done." "\n[Build] Error:\n" -echo -n "[Build] Compiling initfsgen..." -run "./build.sh" " done." "\n[Build] Error:\n" -echo -n "[Build] Giving permissions to execute initfsgen..." -run "chmod +x ./initfsgen" " done." "\n[Build] Error:\n" -echo -n "[Build] Exiting directory..." -run "cd ../.." " done." "\n[Build] Error:\n" -echo "[Build] Initfsgen executable built." - -echo "[Build] Generating initfs:" -echo -n "[Build] Changing directory..." -run "cd Blastproof/initfsgen" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up..." -run "rm -f initfs.bin initfs-footprint.bin signsyst.bin" " done." "\n[Build] Error:\n" -echo -n "[Build] Generating initfs..." -run "./initfsgen ../../../initfs_dir" " done." "\n[Build] Error:\n" -echo -n "[Build] Exiting directory..." -run "cd ../.." " done." "\n[Build] Error:\n" -echo "[Build] Initfs generated." - -echo "[Build] Setting up GUIDs:" -echo -n "[Build] Removing old configuration..." -run "rm -f Blastproof/config/bp.conf" " done." "\n[Build] Error:\n" -echo -n "[Build] Generating GUIDs..." -INITFS_TYPE_GUID="8362b434-d825-11f0-a68f-10ffe08423a6" -SIGNSYST_TYPE_GUID="da0048b4-d826-11f0-b877-10ffe08423a6" -INITFS_GUID=$(uuidgen) -SIGNSYST_GUID=$(uuidgen) -echo " done." -echo -n "[Build] Copying configuration..." -run "cp Blastproof/config/bp_template.conf Blastproof/config/bp.conf" " done." "\n[Build] Error:\n" -echo -n "[Build] Patching configuration for InitFS configuration..." -run "sed -i -E \"s/=(UUID_GENERATION_NEEDED_INITFS)/=$INITFS_GUID/\" Blastproof/config/bp.conf" " done." "\n[Build] Error:\n" -echo -n "[Build] Patching configuration for SignSyst configuration..." -run "sed -i -E \"s/=(UUID_GENERATION_NEEDED_SIGNSYST)/=$SIGNSYST_GUID/\" Blastproof/config/bp.conf" " done." "\n[Build] Error:\n" -echo "[Build] GUIDs setup completed." - -echo "[Build] Building keygen:" -echo -n "[Build] Changing directory..." -run "cd Blastproof/keygen" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up directories..." -run "rm argon2 -rf" " done." "\n[Build] Error:\n" -echo -n "[Build] Cleaning up files..." -run "rm keygen libargon2.a argon2.h -f" " done." "\n[Build] Error:\n" -echo -n "[Build] Cloning argon2..." -run "wget https://github.com/P-H-C/phc-winner-argon2/archive/refs/heads/master.zip" " done." "\n[Build] Error:\n" -echo -n "[Build] Unziping argon2..." -run "unzip -qo master.zip" " done." "\n[Build] Error:\n" -echo -n "[Build] Renamming argon2 folder..." -run "mv phc-winner-argon2-master argon2" " done." "\n[Build] Error:\n" -echo -n "[Build] Removing downloaded archive..." -run "rm master.zip" " done." "\n[Build] Error:\n" -echo -n "[Build] Changing directory..." -run "cd argon2" " done." "\n[Build] Error:\n" -echo -n "[Build] Compiling argon2..." -run "make" " done." "\n[Build] Error:\n" -echo -n "[Build] Exiting directory..." -run "cd .." " done." "\n[Build] Error:\n" -echo -n "[Build] Moving argon2 library..." -run "mv ./argon2/libargon2.a ./libargon2.a" " done." "\n[Build] Error:\n" -echo -n "[Build] Moving argon2 header..." -run "mv ./argon2/include/argon2.h ./argon2.h" " done." "\n[Build] Error:\n" -echo -n "[Build] Compiling keygen..." -run "./build.sh" " done." "\n[Build] Error:\n" -echo -n "[Build] Giving permissions to execute keygen..." -run "chmod +x keygen" " done." "\n[Build] Error:\n" -echo -n "[Build] Exiting folder..." -run "cd .." " done." "\n[Build] Error:\n" -echo "[Build] Keygen executable built." - -echo "[Build] Generating key for important files:" -echo "[Build] Obtaining permissions:" -sudo echo -n "" -echo -e "[Build] Running keygen:\n" -sudo ./keygen/keygen ./config/bp.conf ./fontgen/bitra-ascii-medium.fbm ./initfsgen/initfs-footprint.bin ./initfsgen/signsyst-hash.bin -echo -n "[Build] Moving generated header file..." -run "sudo mv -f key.h ./src/libs/include/key.h" " done." "\n[Build] Error:\n" -echo "[Build] Keys generated." - -echo "[Build] Building Blastproof:" -echo -n "[Build] Changing directory..." -run "cd .." " done." "\n[Build] Error:\n" -echo -n "[Build] Building Blastproof..." -run "build --platform=Blastproof/blastproof.dsc --module=Blastproof/src/main.inf --arch=X64 --buildtarget=RELEASE --tagname=GCC" " done." "\n[Build] Error:\n" -echo "[Build] Blastproof built." - -echo "[Build] Building disk image:" -echo -n "[Build] Removing old disk image..." -run "rm -rf disk.img" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating a new disk image..." -run "fallocate -l 1024M disk.img" " done." "\n[Build] Error:\n" -echo -n "[Build] Mounting disk image..." -run "LPDEV=$(sudo losetup --find --show disk.img)" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating GPT table..." -run "sudo parted "$LPDEV" --script mklabel gpt" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating EFI partition..." -run "sudo parted "$LPDEV" --script mkpart ESP fat32 1MiB 100Mib" " done." "\n[Build] Error:\n" -echo -n "[Build] Making EFI partition bootable..." -run "sudo parted "$LPDEV" --script set 1 esp on" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating FAT32 filesystem on EFI partition..." -run "sudo mkfs.fat -F32 "${LPDEV}p1"" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating mount point..." -run "sudo mkdir -p ./efi-part" " done." "\n[Build] Error:\n" -echo -n "[Build] Mounting EFI partition..." -run "sudo mount "${LPDEV}p1" ./efi-part" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating folder (1/3)..." -run "sudo mkdir -p ./efi-part/EFI/BOOT" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating folder (2/3)..." -run "sudo mkdir -p ./efi-part/EFI/BlastProofFiles" " done." "\n[Build] Error:\n" -echo -n "[Build] Copying file (1/5)..." -run "sudo cp Blastproof/bootanim/bootanim.bin ./efi-part/EFI/BlastProofFiles/bootanim.bin" " done." "\n[Build] Error:\n" -echo -n "[Build] Copying file (2/5)..." -run "sudo cp Blastproof/config/bp.conf ./efi-part/EFI/BlastProofFiles/bp.conf" " done." "\n[Build] Error:\n" -echo -n "[Build] Copying file (3/5)..." -run "sudo cp Blastproof/fontgen/bitra-ascii-medium.fbm ./efi-part/EFI/BlastProofFiles/bitra-ascii-medium.fbm" " done." "\n[Build] Error:\n" -echo -n "[Build] Copying file (4/5)..." -run "sudo cp Blastproof/initfsgen/initfs-footprint.bin ./efi-part/EFI/BlastProofFiles/initfs-footprint.bin" " done." "\n[Build] Error:\n" -echo -n "[Build] Copying file (5/5)..." -run "sudo cp Blastproof/initfsgen/signsyst-hash.bin ./efi-part/EFI/BlastProofFiles/signsyst-hash.bin" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating folder (3/3)..." -run "sudo mkdir -p ./efi-part/EFI/BlastProofSign" " done." "\n[Build] Error:\n" -echo -n "[Build] Copying all signatures files..." -run "sudo cp Blastproof/sign/* ./efi-part/EFI/BlastProofSign/" " done." "\n[Build] Error:\n" -echo -n "[Build] Copying bootloader..." -run "sudo cp Build/BlastproofEnv/RELEASE_GCC/X64/BlastMain.efi ./efi-part/EFI/BOOT/BOOTX64.EFI" " done." "\n[Build] Error:\n" -echo -n "[Build] Unmounting EFI partition..." -run "sudo umount ./efi-part" " done." "\n[Build] Error:\n" -echo -n "[Build] Creating InitFS partition..." -INITFS_BIN="Blastproof/initfsgen/initfs.bin" -INITFS_SIZE_BYTES=$(stat -c '%s' "$INITFS_BIN") -INITFS_SIZE_ALIGNED=$((INITFS_SIZE_BYTES/512+1)) -SIZE="+${INITFS_SIZE_ALIGNED}" -run "sudo sgdisk \ - --new=2:0:${SIZE} \ - --typecode=2:${INITFS_TYPE_GUID} \ - --partition-guid=2:${INITFS_GUID} \ - --change-name=2:\"InitFS\" \ - \"${LPDEV}\"" " done." "\n[Build] Error:\n" - echo -n "[Build] Creating SignSyst partition..." -SIGNSYST_BIN="Blastproof/initfsgen/signsyst.bin" -SIGNSYST_SIZE_BYTES=$(stat -c '%s' "$SIGNSYST_BIN") -SIGNSYST_SIZE_ALIGNED=$((SIGNSYST_SIZE_BYTES/512+1)) -SIZE="+${SIGNSYST_SIZE_ALIGNED}" -run "sudo sgdisk \ - --new=3:0:${SIZE} \ - --typecode=3:${SIGNSYST_TYPE_GUID} \ - --partition-guid=3:${SIGNSYST_GUID} \ - --change-name=3:\"SignSyst\" \ - \"${LPDEV}\"" " done." "\n[Build] Error:\n" -echo -n "[Build] Syncing partition table..." -run "sudo partprobe \"$LPDEV\"" " done." "\n[Build] Error:\n" -echo -n "[Build] Flashing InitFS..." -run "sudo dd if=Blastproof/initfsgen/initfs.bin of="${LPDEV}p2" bs=4M conv=fsync" " done." "\n[Build] Error:\n" -echo -n "[Build] Flashing SignSyst..." -run "sudo dd if=Blastproof/initfsgen/signsyst.bin of="${LPDEV}p3" bs=4M conv=fsync" " done." "\n[Build] Error:\n" -echo -n "[Build] Unmounting disk image..." -run "sudo losetup -d "$LPDEV"" " done." "\n[Build] Error:\n" -echo "[Build] Launching QEMU with disk image" -qemu-system-x86_64 \ - -drive if=pflash,format=raw,unit=0,readonly=on,file=Build/OvmfX64/RELEASE_GCC/FV/OVMF_CODE.fd \ - -drive file=disk.img,format=raw,if=virtio,index=0 \ - -serial stdio \ - -m 4096M \ - -cpu host \ - -enable-kvm diff --git a/common/versions.h b/common/versions.h new file mode 100644 index 0000000..30e69bf --- /dev/null +++ b/common/versions.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MPL-2.0 +// This file provide the versions of all the components of Vystem +#ifndef VY_COMMON_VERSIONS +#define VY_COMMON_VERSIONS +#define VY_COMMON_VERSIONS_OS 0x00000002 +#define VY_COMMON_VERSIONS_BOOTLOADER 0x0002 +#define VY_COMMON_VERSIONS_INITFS 0x0001 +#define VY_COMMON_VERSIONS_VYX 0x0002 +#define VY_COMMON_VERSIONS_MANIFEST 0x0001 +#endif diff --git a/disk.json b/disk.json new file mode 100644 index 0000000..7450c6c --- /dev/null +++ b/disk.json @@ -0,0 +1,72 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Disk image build", + "actions":[ + { + "action":"create_disk", + "args":{ + "key_variables":false, + "key":"disk", + "size":157286400, + "disk_guid_variables":true, + "disk_guid":"$DISK_GUID$" + } + }, + { + "action":"add_partition_disk", + "args":{ + "key_variables":true, + "key":"disk", + "type_guid_variables":true, + "type_guid":"$ESP_PARTITION_TYPE_GUID$", + "unique_guid_variables":true, + "unique_guid":"$ESP_PARTITION_UNIQUE_GUID$", + "name_variables":false, + "name":"Vystem ESP Partition", + "source_file_variables":true, + "source_file":"%rootcallerfolder%/$EDK2_DIR$/esp.bin" + } + }, + { + "action":"add_partition_disk", + "args":{ + "key_variables":true, + "key":"disk", + "type_guid_variables":true, + "type_guid":"$INITFS_PARTITION_TYPE_GUID$", + "unique_guid_variables":true, + "unique_guid":"$INITFS_UNIQUE_UUID$", + "name_variables":false, + "name":"InitFS", + "source_file_variables":true, + "source_file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/initfsgen/initfs.bin" + } + }, + { + "action":"add_partition_disk", + "args":{ + "key_variables":true, + "key":"disk", + "type_guid_variables":true, + "type_guid":"$SIGNSYST_PARTITION_TYPE_GUID$", + "unique_guid_variables":true, + "unique_guid":"$SIGNSYST_UNIQUE_UUID$", + "name_variables":false, + "name":"SignSyst", + "source_file_variables":true, + "source_file":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/initfsgen/signsyst.bin" + } + }, + { + "action":"export_disk", + "args":{ + "key_variables":false, + "key":"disk", + "export_path_variables":true, + "export_path":"%rootcallerfolder%/$EDK2_DIR$/disk.bin" + } + } + ] +} diff --git a/docs/blastproof/bootconfig.md b/docs/blastproof/bootconfig.md index 7375ed5..9c5aace 100644 --- a/docs/blastproof/bootconfig.md +++ b/docs/blastproof/bootconfig.md @@ -2,7 +2,7 @@ ## Introduction -Blastproof store his configuration inside a text file named `bp.conf` and stored inside `\EFI\BlastProofFiles` inside the EFI partition. Due to being protected by SBFIE, the config is immutable after compilation and any change to it will cause the boot to fail, even if provided password was good. A example configuration is provided as `Blastproof/config/bp_template.conf` +Blastproof store his configuration inside a text file named `bp.conf` and stored inside `\EFI\BPFILES` inside the EFI partition. Due to being protected by SBFIE, the config is immutable after compilation and any change to it will cause the boot to fail, even if provided password was good. A example configuration is provided as `Blastproof/config/bp_template.conf` ## Syntax and behaviour @@ -38,7 +38,7 @@ Any non-ascii character will cause the boot to fail. All the keys that are liste **font:** - Description: Give the name of the file containing the font the bootloader will atempt to use. -- Possible value: any value representing a file name stored inside `EFI\BlastProofFiles` +- Possible value: any value representing a file name stored inside `EFI\BPFILES` - Default value: `bitra-ascii-medium.fbm` **disable_boot_animation:** @@ -109,3 +109,8 @@ Any non-ascii character will cause the boot to fail. All the keys that are liste - Description: define the amount of pages used for logging ring buffer. Setting this pair to 0 will disable the logging ring. - Possible value: any integer ranging from 0 to 65535 - Default value: `2048` + +**kernel_kbd_events_queue_capacity** +- Description: define the amount of keyboards events each keyboard events can hold +- Possible value: any integer ranging from 64 to 65535 +- Default value: `256` diff --git a/docs/blastproof/bootprocess.md b/docs/blastproof/bootprocess.md index 38e358d..2cf9cea 100644 --- a/docs/blastproof/bootprocess.md +++ b/docs/blastproof/bootprocess.md @@ -2,10 +2,7 @@ Blastproof boot process follow a very rigid sequences of steps that are detailled below: -- Printing informations: - - Bootloader version - - Firmware informations - - CPU informations +- Verifying VFTM - Reading boot password from EFI console - Verifying integrity of integrated keys (see SBFIE) - Acquiring access to ESP partition @@ -20,14 +17,14 @@ Blastproof boot process follow a very rigid sequences of steps that are detaille - Loading and rendering bitmap font according to selected graphic output format - Loading, rendering and playing boot animation if configuration allow it - Loading InitFS and SignSyst - - Listing all availables BlockIO protocol - - Locating handles for InitFS and SignSyst + - Parsing the GPT table on which the ESP is located - Allocating memory for them - Loading them into RAM - Parsing their headers - Performing cryptographic checks to validate their headers and contents - Loading the kernel - Loading Shelter and Keycard binary + - Obtaining ACPI pointer - Generating Shelter boot configuration - Allocating pages for kernel sections - Creating page table diff --git a/docs/blastproof/bplib.md b/docs/blastproof/bplib.md index 4b14ffc..3d0e9df 100644 --- a/docs/blastproof/bplib.md +++ b/docs/blastproof/bplib.md @@ -29,16 +29,17 @@ The Blastproof bootloader is based on the EDK II framework: Blastproof library is divided into several components, some relying on the external libraries cited above, and all relying on the EDK II framework. Here is the list of all components with their headers: - `conf.h`: manage configuration loading and parsing -- `console.h`: provide a simple way to enter a password inside the EFI shell -- `cpu.h`: provide a simple way to print CPU ID informations -- `crypto.h`: provide the cryptographic abstraction layer to use algorithms such as Argon2, SHA3 or Sphincs+ -- `debug.h`: provide outputting primitives to the serial port -- `default.h`: provide macros for default configuration values -- `disk.h`: provide functions to read files from ESP partition -- `font.h`: provide functions to load, parse and render FBM fonts -- `graphic.h`: provide basic primitives to interact with GOP framebuffers +- `console.h`: provides a simple way to enter a password inside the EFI shell +- `cpu.h`: provides a simple way to print CPU ID informations +- `crypto.h`: provides the cryptographic abstraction layer to use algorithms such as Argon2, SHA3 or Sphincs+ +- `debug.h`: provides outputting primitives to the serial port +- `default.h`: provides macros for default configuration values +- `disk.h`: provides functions to read files from ESP partition +- `font.h`: provides functions to load, parse and render FBM fonts +- `graphic.h`: provides basic primitives to interact with GOP framebuffers - `initfs.h`: InitFS and SignSyst drivers -- `ui.h`: provide primitives to render text and boot animation in the GOP framebuffer -- `vyx.h`: provide a very basic Vyx-based kernel loader +- `ui.h`: provides primitives to render text and boot animation in the GOP framebuffer +- `vyx.h`: provides a very basic Vyx-based kernel loader +- `vftm.h`: verify VFTM authenticity and informations Additional headers can be generated at compilation time and aren't included in this list, such as `key.h`. diff --git a/docs/blastproof/fbm.md b/docs/blastproof/fbm.md index 76a88ca..39f6825 100644 --- a/docs/blastproof/fbm.md +++ b/docs/blastproof/fbm.md @@ -50,4 +50,4 @@ When rendering the font, the renderer will take two values: background color and ## Provided font -Vystem provide a basic font named `bitra`, with 12 pixels as width and 20 as height, only supporting ASCII characters. This font is stored in the file `bitra-medium-ascii.fbm`. +Vystem provides a basic font named `bitra`, with 12 pixels as width and 20 as height, only supporting ASCII characters. This font is stored in the file `FONT.FBM`. diff --git a/docs/blastproof/fs.md b/docs/blastproof/fs.md index df694dd..6c623aa 100644 --- a/docs/blastproof/fs.md +++ b/docs/blastproof/fs.md @@ -15,7 +15,7 @@ The header of any InitFS filesystem is as follow: - Bootloader version: an uint16_t indicating the bootloader version, currently set to `0x0001` - InitFS version: an uint16_t indicating the InitFS version, currently set to `0x0001` - OS version: an uint32_t indicating the OS version, currently set to `0x00000001` -- Installation ID: an array of 48 completely random bytes. His SHA3-512 hash is stored inside the `initfs-footprint.bin` file, protected by SPFIE +- Installation ID: an array of 48 completely random bytes. His SHA3-512 hash is stored inside the `INITFSFP.BIN` file, protected by SBFIE - InitFS Size: the amount of bytes in the total filesystem, not forcefully rounded to the disk block size. Stored as an uint64_t - Files table size: the amount of bytes used for the filesystem files table. Stored as an uint64_t - Files content size: the amount of bytes for the filesystem files content area. Stored as an uint64_t @@ -26,11 +26,11 @@ The header of any InitFS filesystem is as follow: - Entropy check: 8 bytes of a value generated with this formula : `header.entropy_check=(header.entropy*0x9E3779B185EBCA87)^header.entropy`. Stored as an uint64_t - Files table hash: an array of 64 bytes containing the SHA3-512 hash of the files table - Files content area hash: an array of 64 bytes containig the SHA3-512 hash of the files content area -- Installation ID double hash: an array of 64 bytes containing the SHA3-512 hash of the content of the `initfs-footprint.bin` file. +- Installation ID double hash: an array of 64 bytes containing the SHA3-512 hash of the content of the `INITFSFP.BIN` file. - Padding: 128 bytes of padding generated with a specific pattern (see below) - Header hash: an array of 64 bytes containing the SHA3-512 of the InitFS header, not including the last 64 bytes -This header is exactly 512 bytes. The mecanism decribed above with the installation ID and the `initfs-footprint.bin` is to ensure that an installation of Blastproof find his associated InitFS. +This header is exactly 512 bytes. The mecanism decribed above with the installation ID and the `INITFSFP.BIN` is to ensure that an installation of Blastproof find his associated InitFS. ### Files table and files entries @@ -67,7 +67,7 @@ The header of any SignSyst is as follow: - Padding: 288 bytes of padding generated with the same pattern as InitFS - Header hash: an array of 64 bytes containing the SHA3-512 of the SignSyst header, not including the last 64 bytes -The header is exactly 512 bytes. The file `signsyst-hash.bin`, protected by SPFIE, contain the full hash of the SignSyst header. +The header is exactly 512 bytes. The file `SSHASH.BIN`, protected by SBFIE, contain the full hash of the SignSyst header. ### Signatues area diff --git a/docs/blastproof/index.md b/docs/blastproof/index.md index 72207b2..6feb4ba 100644 --- a/docs/blastproof/index.md +++ b/docs/blastproof/index.md @@ -2,20 +2,22 @@ ## Introduction -Blastproof is Vystem's bootloader. It is a UEFI x86-64 only bootloader that rely on EDK II for all hardware interactions. It is able to confirm the integrity of his files, locate the kernel and load it into memory, using the specific boot protocol designed for Shelter. +Blastproof is Vystem's bootloader. It is a UEFI x86-64 only bootloader that rely on EDK II for all hardware interactions. It is able to confirm the integrity of his files and partition, locate the kernel and load it into memory, using the specific boot protocol designed for Shelter. ## Blastproof architectural overview -The Blastproof bootloader rely mainly on the EDK II framework for printing to the EFI console, interacting with disks/partitions and FAT32 filesystem, graphic output protocol, and memory allocation. However, it uses Vystem standard formats for fonts, filesystems, security and integrity checks, graphic renderer, and kernel loading. +The Blastproof bootloader rely mainly on the EDK II framework for printing to the EFI console, interacting with disks and FAT32 filesystem, graphic output protocol, and memory allocation. However, it uses Vystem standard formats for fonts, filesystems, security and integrity checks, graphic renderer, and kernel loading. ## Ressources 1) [Bootprocess](bootprocess.md) +2) [Keyboard layouts](kbdlayout.md) 2) [Boot configuration](bootconfig.md) 3) [Security and integrity model at boot level](security.md) -4) [Secure Boot Files Integrity Enforcement (SBFIE)](sbfie.md) -5) [Custom filesystems](fs.md) -6) [Font Bitmap](fbm.md) -7) [Blastproof library](bplib.md) +4) [Vystem FAT Trusted Manifest](vftm.md) +5) [Secure Boot Files Integrity Enforcement (SBFIE)](sbfie.md) +6) [Custom filesystems](fs.md) +7) [Font Bitmap](fbm.md) +8) [Blastproof library](bplib.md) For detailled informations about kernel loading, please see Vyld docs. diff --git a/docs/blastproof/kbdlayout.md b/docs/blastproof/kbdlayout.md new file mode 100644 index 0000000..8fb6bec --- /dev/null +++ b/docs/blastproof/kbdlayout.md @@ -0,0 +1,71 @@ +# Keyboard layouts + +## Introduction + +Blastproof supports the addition of custom keyboards layout. This file describe how they are structured and how to create one. + +## Implementation + +The `layout.h` header, located in `Blastproof/src/libs/include`, contain the utilities needed to create custom keyboards layout. Two main structures are needed: + +``` C +typedef struct { + CHAR16 char_source; + CHAR16 char_dest; +} bp_layout_CHAR_CONV; +``` +The `char_source` field must be the character that Blastproof will receive from the UEFI firmware. In the immense majority of case, the firmware interprets each pressed key using the QWERTY layout. The `char_dest` field must be the character that replaced the inputed character. + +``` C +typedef struct { + UINTN conv_count; + bp_layout_CHAR_CONV conv_table[]; +} bp_layout_CONV_TABLE; +``` +This structure is defined at compilation time and should indicate the amount of characters conversions as well as all the characters conversions, stored in an array. + +## Usage + +In the immense majority of cases, the firmware uses the QWERTY layout. If this is the case, you should use the keyboard layout of your keyboard. Here are the supported keyboard layout for the moment: + +- `QWERTY` +- `AZERTY` + +In the case where the firmware already use the keyboard layout of your keyboard, please select the `QWERTY` layout : it doesn't contain any key translation. + +## Creating your own layout + +In order to create your own keyboard layout, you can follow these steps: + +### Creating the header file + +1) Create a header file named `.h` inside the `Blastproof/src/libs/include/layouts` folder. + +2) Paste it the following template: + +``` C +// SPDX-License-Identifier: MPL-2.0 +#ifndef BP_LIB_LAYOUT_LAYOUTNAME_H +#define BP_LIB_LAYOUT_LAYOUTNAME_H +#include "../layout.h" +bp_layout_CONV_TABLE layoutname_convs={ + .conv_count=0, + .conv_table={ + } +}; +#endif +``` + +3) Replace every `layoutname` and `LAYOUTNAME` with the name of your layout. + +4) Add as many character conversions as you want. A character conversion is set under the form `{L'a',L'q'}`. In this example, we translate the character `a` to `q`. + +5) Don't forget to update the `conv_count` field with the amount of characters conversions. + +### Registering the layout + +Go inside the `layout_registry.h` file, located inside `Blastproof/src/libs/include/layouts` and add the following line where indicated: +- `#include ".h"` : replace `` with the name of your layout +- add the string that will be displayed (generally the layout name) to the user inside +`layout_list`. Don't forger the `L` string modifier before the first quote +- `&_conv` : add this element inside the `layout_conversions_table` variable. Don't forget the `&` operator diff --git a/docs/blastproof/sbfie.md b/docs/blastproof/sbfie.md index cbd50d7..8504f96 100644 --- a/docs/blastproof/sbfie.md +++ b/docs/blastproof/sbfie.md @@ -12,7 +12,7 @@ SBFIE has been conceived with the following limitations in mind: - due to the will of it being compatible with a large variety of devices, it doesn't integrate TPM utilization (but support in an eventual future is planned) - any user of a non-QWERTY keyboard will have a hard time typing a password in an UEFI console - it use the EFI console as input (support of self-made input methods and protocol will be implemented in a near future) -- any missing file that is supposed to be protected by SPFIE will cause the boot process to fail +- any missing file that is supposed to be protected by SBFIE will cause the boot process to fail ## How it work @@ -27,15 +27,16 @@ The `key.h` header contain the following datas: - `bp_key_pkblob`: an array of `64*N` bytes containing `N` Sphincs+ public keys, one for each file - `bp_key_pwdsalt`: an array of 32 bytes containing the salt to use for hashing the boot password - `bp_key_files`: an array of `N` strings indicating the order in which boot files should be verified for each public key from `sh_key_pkblob` to correspond with each file +- `bp_key_files_sign`: an array of `N` strings indicating the corresponding signature file for each file of `bp_key_files` -We assume that all files are in the `\EFI\BlastProofFiles` folder with their corresponding names as specified in `bp_key_files` and that their Sphincs+ signatures are stored as `.sig` inside of the `\EFI\BlastProofSign` folder. +We assume that all files are in the `\EFI\BPFILES` folder with their corresponding names as specified in `bp_key_files` and that their Sphincs+ signatures are stored inside `bp_key_files_sign` as `.sig` inside of the `\EFI\BPSIGN` folder. ### Detailled steps -The steps in which SPFIE check the files is as follow: +The steps in which SBFIE check the files is as follow: 1. The user enter the boot password -2. The boot password is hashed using Argon2 using 262144 of memory cost and 3 of time cost. The salt is stored inside `bp_key_pwdsalt`The output is a 96 digest. +2. The boot password is hashed using Argon2 using 262144 of memory cost and 3 of time cost. The salt is stored inside `bp_key_pwdsalt`. The output is a 96 digest. 3. The digest is used as seed for generating a Sphincs+ keypair, immediately erasing the private key and keeping only the public key. 4. The generated public key is used to verify the signature inside `bp_key_mainsig` with the message being `bp_key_pkblob` 5. If the verification is successfull, the boot process continue. If not, the boot process is halted. @@ -46,8 +47,8 @@ The steps in which SPFIE check the files is as follow: ## Concerned files -To this date, the following files generated by build script are protected by SPFIE: -- `bp.conf` -- `bitra-ascii-medium.fbm` -- `initfs-footprint.bin` -- `signsyst-hash.bin` +To this date, the following files generated by build script are protected by SBFIE: +- `BP.CFG` +- `FONT.FBM` +- `INITFSFP.BIN` +- `SSHASH.BIN` diff --git a/docs/blastproof/security.md b/docs/blastproof/security.md index 6fda35f..0170c2a 100644 --- a/docs/blastproof/security.md +++ b/docs/blastproof/security.md @@ -7,9 +7,10 @@ The Vystem project has been designed for the ground up for security and integrit ## Overview In order to achieve a strong amount of security without sacrificing compatibility with existing devices, we have chosen to integrate the following elements into the boot sequence: -- Secure Boot Files Integrity Enforcement (SBFIE): protect cores bootloader files assuming bootloader integrity with a user-defined password, without storing it directly but integrating it very deeply in the integrity check chain. See [SPFIE docs](spfie.md) for more informations +- Vystem FAT Trusted Manifest (VFTM): ensure that the FAT32 filesystem on the ESP partition was produced by an authorized entity, that the ESP partition hasn't been changed from disk, that the FAT32 filesystem hasn't been corrupted or modified, and allow for the bootloader to check his own binary without EFI Secure Boot. It's signed by Keygen and verified by the bootloader himself. See [VFTM docs](vftm.md) for more informations. +- Secure Boot Files Integrity Enforcement (SBFIE): protect cores bootloader files assuming bootloader integrity with a user-defined password, without storing it directly but integrating it very deeply in the integrity check chain. See [SBFIE docs](sbfie.md) for more informations - Robust post-quantum cryptography integrated directly into the bootloader: while we rely on EDK II for files and disk IO as well as password input, all the cryptography stack is integrated into the bootloader, not relying on firmware cryptography at any time. We use post-quantum signing algorithm like SPHINCS+ and strong hashing primitives like Argon2 and SHA3, with their sources codes directly taken from their official implementation, only modified to integrate with EDK II types and memory allocation system -- Signing of every system files: every sensitive system file is integrated into the InitFS, signed into a trio of check: each Blastproof binary (and so SPFIE keys), InitFS and SignSyst is uniquely associated (mainly by installation ID), meaning that the whole system can only work if all of them are properly setup on the same machine device. InitFS integrity check are also cryptographically linked to SPFIE verification. +- Signing of every system files: every sensitive system file is integrated into the InitFS, signed into a trio of check: each Blastproof binary (and so SBFIE keys), InitFS and SignSyst is uniquely associated (mainly by installation ID), meaning that the whole system can only work if all of them are properly setup on the same machine device. InitFS integrity check are also cryptographically linked to SBFIE verification. ## Limitations diff --git a/docs/blastproof/vftm.md b/docs/blastproof/vftm.md new file mode 100644 index 0000000..e32e515 --- /dev/null +++ b/docs/blastproof/vftm.md @@ -0,0 +1,92 @@ +# Vystem FAT Trusted Manifest + +## Introduction + +Vystem FAT Trusted Manifest (VFTM) is a structure that can be found in the reserved sectors of any FAT32 filesystem generated by VyBuild (please see the conditions for VyBuild to generate this manifest in the VyBuild documentation). It's the first layer of defense in the Vystem Secure Boot Chain, being verified independantly at each boot. + +## Position and structure + +VTFM can be divided into three parts: +- the VFTM manifest itself, containing all importants informations and hashs. It's stored somewhere between the sector 8 and 31 of the FAT32 filesystem +- the manifest public key. It's stored somewhere between the sector 8 and 31 of the FAT32 filesystem, but never on the same sector of the manifest itself +- the manifest signature. It's stored after the FAT32 filesystem, just before the end of the ESP partition + +The manifest and manifest public key have their position determined by this function: +``` C +void generate_vftm_sectors(const uint8_t* part_guid,int* sector_manifest,int* sector_public_key) { + uint32_t h=0x811c9dc5; + for (int i=0;i<16;i++) h=(h^part_guid[i])*0x01000193; + *sector_manifest=8+(h%24); + *sector_public_key=8+(((h>>16)%23+(*sector_manifest-7))%24); +} +``` + +The `part_guid` argument is an array of 16 bytes containing the ESP partition unique GUID. That way, the position of these components of VFTM is linked to the GPT table. + +## Generation of the keys + +Two Sphincs+ keypairs are generated by the Keygen utility. They are named `root` and `manifest`. We use `sk_root` to sign `pk_manifest`, generating the signature `sig_root`. `sig_root` and `pk_root` are injected into the `key.h` header generated by Keygen, alongside the SBFIE stuff. `sk_root` is immediately destroyed and never leave Keygen memory space. Then, using UNIX socket named `vftm.sock`, that should be created in the current directory by the calling entity of Keygen, Keygen transmit the keypair `manifest` to the calling entity. It should always be the entity that will generate the FAT32 filesystem (in this case, VyBuild). + +VyBuild will sign the generated manifest with `sk_manifest`, and erase it immediately after. `pk_manifest` became the public key that will be injected into one of the reserved sector of the filesystem, alongside the manifest. The generated `sig_manifest` is injected at the end of the ESP partition, right after the FAT32 manifest. + +## Manifest structure + +The manifest structure can be represented like this: +``` C +#pragma pack(1) +struct vystem_fat_trusted_manifest { + uint8_t sig[8]; + uint16_t manifest_version; + uint16_t bootloader_version; + uint32_t os_version; + uint8_t fat_hash[64]; + uint8_t fat_build_id[32]; + uint64_t clusters_count; + uint64_t bytes_per_sector; + uint64_t sectors_per_cluster; + uint64_t fat_size_bytes; + uint64_t fat_offset_bytes; + uint64_t bootloader_cluster_count; + uint64_t bootloader_cluster_offset; + uint64_t bootloader_build_id; + uint8_t fat_header_hash[64]; + uint8_t bootloader_binary_hash[64]; + uint64_t signature_offset_bytes; + uint64_t signature_size; + uint8_t gpt_disk_guid[16]; + uint8_t gpt_efi_part_unique_guid[16]; + uint8_t manifest_hash[64]; +}; +#pragma pack() +``` + +The expected signature is `VyFatSig` in ASCII. + +## VFTM detailled verification procedure + +Before doing anything, the bootloader will do all these steps to verify the authenticity, then the content of the manifest: + +### VFTM assets gathering + +The bootloader will gather the following assets in order, using various EDK2 protocols: +- the disk GUID from the GPT header +- the ESP partition unique GUID, that will serve to determine where to extract the manifest and public key +- the manifest and public key +- the manifest signature + +### Keys verification + +The booloader will then do the following steps to confirm the manifest authenticity: +1) Using `pk_root` and `sig_root`, it verify the extracted `pk_manifest`. If this fail, the bootprocess is halted. +2) Using `pk_manifest` and `sig_manifest`, it verify the extracted manifest. If this fail, the bootprocess is halted. + +### Manifest contents verification + +Finally, it can use the manifest content to verify various things in this order: +1) Verify the indicated manifest signature, various versions and GUID provided into the manifest. +2) Verify the FAT32 header by comparing his hash and fields with what is provided into the manifest. +3) Verify the FATs by hashing the FATs found in the filesystem and comparing them with the hash provided into the manifest. +4) Verify the bootloader binary by hashing it (retrieving his content through metadatas contained inside the manifest, without using the SimpleFilesystemProtocol) and comparing it to the hash provided into the manifest +5) Verify the hash of the manifest + +All hashs use the SHA3-512 algorithm. diff --git a/docs/boottools/commoncrypto.md b/docs/boottools/commoncrypto.md new file mode 100644 index 0000000..7bc671e --- /dev/null +++ b/docs/boottools/commoncrypto.md @@ -0,0 +1,18 @@ +# Common crypto docs + +## Introduction + +The `commoncrypto` library is responsible for providing all cryptographic functions necessary to `keygen`, `initfsgen` and later VyBuild + +## Detailled informations + +Folder: `Blastproof/commoncrypto` + +It's build using VyBuild, as both a static and shared library. The provided build file doesn't allow yet for the library to be build outside of Vystem build process. + +The `-Ofast -march=native` is used on every source file, to make it faster in every use case. + +The library include the following external cryptographic library: +- SPHINCS+, made by the SPHINCS+ team, sourced from [sphincs/sphincsplus](https://github.com/sphincs/sphincsplus), under the MIT-0 license +- tiny_sha3, made by mjosaarinen, sourced from [mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3), under the MIT license +- Argon2, made by the Argon2 team, sourced from [P-H-C/phc-winner-argon2](https://github.com/P-H-C/phc-winner-argon2), under the CC0-1.0 license diff --git a/docs/boottools/index.md b/docs/boottools/index.md index 917d22e..a486c52 100644 --- a/docs/boottools/index.md +++ b/docs/boottools/index.md @@ -1,10 +1,11 @@ # Bootloader tools Docs -In order to generate all necessary components for the build of a Vystem disk image, we have created several C++ tools designed to help generating these components. All of these tools have been intented to be used only in a normal Linux environnement. Here is the list of bootloader tools: -1) [bootanim](bootanim.md) -2) [fontgen](fontgen.md) -3) [initfsgen](initfsgen.md) -4) [keygen](keygen.md) +In order to generate all necessary components for the build of a Vystem disk image, we have created several C++ tools and library designed to help generating these components. All of these tools have been intented to be used only in a normal Linux environnement. Here is the list of bootloader tools: +1) [commoncrypto](commoncrypto.md) +2) [bootanim](bootanim.md) +3) [fontgen](fontgen.md) +4) [initfsgen](initfsgen.md) +5) [keygen](keygen.md) Here a few precisions about the global mecanisms inside each tools: - when a tool is iterating on the content of a folder, it rely on the order provided by the filesystem. But tool like `keygen` get there files list through arguments specifying direct files path rather than a folder path, making it a deterministic order if the build script doesn't change diff --git a/docs/boottools/initfsgen.md b/docs/boottools/initfsgen.md index 91e6475..ca9b61f 100644 --- a/docs/boottools/initfsgen.md +++ b/docs/boottools/initfsgen.md @@ -9,9 +9,9 @@ The `initfsgen` utility is responsible for generating the InitFS and SignSyst fi Folder: `Blastproof/initfsgen` Source code file: `initfsgen.cpp` -For building `initfsgen`, use the provided build script `build.sh` while being in the utility directory. +For building `initfsgen`, you will need to use the provided build file. But for the moment, the provided build file doesn't allow yet for the utility to be build outside of Vystem build process. The build file will require `libcommoncrypto.a` to be provided inside the `initfsgen` folder. -External library: +External library provided by `commoncrypto` and used inside `initfsgen`: - SPHINCS+, made by the SPHINCS+ team, sourced from [sphincs/sphincsplus](https://github.com/sphincs/sphincsplus), under the MIT-0 license - tiny_sha3, made by mjosaarinen, sourced from [mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3), under the MIT license @@ -35,16 +35,16 @@ initfsgen ./initfs_dir 2) Collect 48 bytes of entropy for installation ID and 8 bytes of entropy for entropy check, by opening `/dev/urandom`. No others method of entropy generation are or will be supported. 3) Copying installation ID inside InitFS and SignSyst headers, filling all possible informations about files and signatures quantity and sizes inside the headers. 4) Generating entropy check, putting it into InitFS header. -5) Computing installation ID hash and saving it into `initfs-footprint.bin`, saved into the current directory. -6) Computing hash of the content of `initfs-footprint.bin` and saving it into the InitFS header. +5) Computing installation ID hash and saving it into `initfsfp.bin`, saved into the current directory. +6) Computing hash of the content of `initfsfp.bin` and saving it into the InitFS header. 7) Iterate for each file: loading the entire file, generating InitFS file name, copying file data into files content area, computing file content hash, generating SPHINCS+ keypair unique to this file, generating signature for file by using private key, securely erasing private key (without compiler optimization), saving file hash and public key into file entry, saving file entry into files table and adding generated signature to SignSyst 8) Generating files table, files content area and signatures area hash, saving them into headers by xoring them with part of the installation ID 9) Generating and saving padding for InitFS and SignSyst headers. Computing headers hash and finalizing filesystems raw data. -10) Saving InitFS under `initfs.bin`, hashing SignSyst header and saving it into `signsyst-hash.bin`, saving SignSyst under `signsyst.bin` +10) Saving InitFS under `initfs.bin`, hashing SignSyst header and saving it into `sshash.bin`, saving SignSyst under `signsyst.bin` For the full and detailled layout of InitFS and SignSyst, please see [customs filesystems docs](../blastproof/fs.md). All hashing operations use SHA3-512. All entropy generations use secure entropy from `/dev/urandom`. This utility generate four files: - `initfs.bin` and `signsyst.bin` are the filesystems expected to be flashed into their respectives partitions on disk -- `initfs-footprint.bin` and `signsyst-hash.bin` are files expected to be protected by SPFIE and put inside the ESP partition +- `initfsfp.bin` and `sshash.bin` are files expected to be protected by SBFIE and put inside the ESP partition diff --git a/docs/boottools/keygen.md b/docs/boottools/keygen.md index 41727ae..b120007 100644 --- a/docs/boottools/keygen.md +++ b/docs/boottools/keygen.md @@ -2,16 +2,16 @@ ## Introduction -The `keygen` utility is responsible for generating SPFIE keys, files and boot password. This file focus on how these ressources are generated and setuped, not how the verification is made at boot time. The explenations in this file are complementary to the informations in [SPFIE docs](../blastproof/spfie.md). +The `keygen` utility is responsible for generating VFTM keys, SBFIE keys, files and boot password. This file focus on how these ressources are generated and setuped, not how the verification is made at boot time. The explenations in this file are complementary to the informations in [SBFIE docs](../blastproof/sbfie.md) and [VFTM docs](../blastproof/vftm.md). ## Detailled informations Folder: `Blastproof/keygen` Source code file: `keygen.cpp` -For building `keygen`, first make sure that you have the `libargon2.a` static library file inside the utility directory. This one and the source of Argon2 for the `keygen` isn't included inside the main Vystem repository but downloaded and compiled by the build script. So you may have to compile Argon2 yourself before compiling `keygen`. To compile `keygen`, use the provided build script `build.sh` while being in the utility directory. +For building `keygen`, use the provided build file. The provided build file doesn't allow yet for the utility to be build outside of Vystem build process. -External libraries: +External libraries provided by `commoncrypto` and used inside `keygen`: - SPHINCS+, made by the SPHINCS+ team, sourced from [sphincs/sphincsplus](https://github.com/sphincs/sphincsplus), under the MIT-0 license - tiny_sha3, made by mjosaarinen, sourced from [mjosaarinen/tiny_sha3](https://github.com/mjosaarinen/tiny_sha3), under the MIT license - Argon2, made by the Argon2 team, sourced from [P-H-C/phc-winner-argon2](https://github.com/P-H-C/phc-winner-argon2), under the CC0-1.0 license @@ -24,19 +24,22 @@ sudo keygen ... ``` You can provide as much paths as you want, as long as they all lead to regular files. -It's recommanded the `keygen` utility be launched as root. +It's necessary the `keygen` utility be launched as root. If the user launched `keygen` using sudo, all created files and folder will be changed of owner to be owned by the user that launched the `keygen` utility. +To transmit the `manifest` keypair to VyBuild, `keygen` expect the `vftm.sock` UNIX socket to be created inside the current folder of execution. The generation process will fail if this socket isn't created by calling entity. +The `VYSTEM_KEYGEN_PASSWORD` environnement variable can be used to transmit a password. If this variable isn't defined of empty, the utility will default on standard input method. This method of transmiting the password should only be used if you are in a test/developpement environnement, and not in production. ## Detailled generation processus -1) Firstly, the `keygen` processus disable all possibilty of process memory dumps or memory swapping before doing anything else. Due the very thight security here, `keygen` should be running as root to ensure his own security. -2) Then, it check for the existence of all the provided files and lock private and public keys buffer as well as signature buffer to ensure that all the secrets aren't dumped on disk due to process fault or swapping. -3) Iterating for all the provided files: loading the file into memory, generating SPHINCS+ keypair for it, computing and signing the SHA3-512 hash of the file content if it's above 1 megabyte, or signing directly the file if under 1 megabyte, securely erasing all temporary keys and signature buffer, saving signature and public key into their dedicated buffer. -4) Saving all signatures into a directory named `sign`, created if non existing, under the name format `.sig`, then securely erasing the signatures buffer -5) Letting the user enter a boot password. If password is empty, it will ask for a number multiple of 2 to generate this many hexadecimal characters that will serve as password, the default amount of hexadecimal characters being 16. If the user enter a password, the user will have to confirm it -6) Checking that the password fill all criterias: should be (not enforced) at least 12 characters, can (enforced) only include ASCII characters due to EFI shell limitations, shouldn't be longer that 512 characters (enforced), and shoudn't use the numerical pad at all (not well supported in the EFI shell, but the user can still use numbers) -7) Offering the user the possibility to translate their password into a QWERTY representation of it, if they doesn't use a QWERTY keyboard. That way, the user can enter his password like he would do on his keyboard but the password that will be hashed will be the password translated in QWERTY. +1) Firstly, the `keygen` processus disable all possibilty of process memory dumps or memory swapping before doing anything else. Due the very thight security here, `keygen` must be running as root to ensure his own security. +2) It generate all the necessary keys for VFTM. Please see VFTM docs for more informations. +3) Verifying if the `VYSTEM_KEYGEN_PASSWORD` environnement variable exists and acting accordingly. +3) Then, it check for the existence of all the provided files and lock private and public keys buffer as well as signature buffer to ensure that all the secrets aren't dumped on disk due to process fault or swapping. +4) Iterating for all the provided files: loading the file into memory, generating SPHINCS+ keypair for it, computing and signing the SHA3-512 hash of the file content if it's above 1 megabyte, or signing directly the file if under 1 megabyte, securely erasing all temporary keys and signature buffer, saving signature and public key into their dedicated buffer. +5) Saving all signatures into a directory named `sign`, created if non existing, under the name format `.sig`, then securely erasing the signatures buffer -**Warning:** This feature is still very experimental, the only translation supported is AZERTY to QWERTY and the user experience is still very unsettling. For testing purposes, it's recommanded using a password with no characters differences between keyboard layout such as `test`, for example compatibility between the AZERTY and QWERTY keyboard. A better password inputing experience with support for various keyboard layout is planned for future release. +The 2 following steps are only executed if the standard password input method is selected: +6) Letting the user enter a boot password. If password is empty, it will ask for a number multiple of 2 to generate this many hexadecimal characters that will serve as password, the default amount of hexadecimal characters being 16. If the user enter a password, the user will have to confirm it +7) Checking that the password fill all criterias: should be (not enforced) at least 12 characters, can (enforced) only include ASCII characters due to EFI shell limitations, shouldn't be longer that 512 characters (enforced), and shoudn't use the numerical pad at all (not well supported in the EFI shell, but the user can still use numbers) 8) Converting the final password to UTF16LE for EFI environnement easier compatibilty. Obtaining 32 bytes of entropy from `/dev/urandom`. Hashing the password with the Argon2id algorithm using no parralelism, time cost of 3 and memory cost of 262144, with the salt, resulting in a 96 bytes output. 9) Using the password as seed for generating a master SPHINCS+ keypair. Generating a signature of the public keys of each files concatenated into a single block. Securely erasing both keys of the master keypair. diff --git a/docs/build.md b/docs/build.md index 2a2d47e..33445b0 100644 --- a/docs/build.md +++ b/docs/build.md @@ -2,53 +2,56 @@ ## Introduction -In this file, we will see how you can build and boot successfully into a VM containing a Vystem disk image. It's recommanded to read the whole documentation for better understanding of why certains parts are necessary. +In this file, we will see how you can build and boot successfully into a VM containing a Vystem disk image or boot a Vystem instance on a real computer. It's recommanded to read the whole documentation for better understanding of why certains parts are necessary. ## Prerequisites -You should have cloned the full repository on your device. Please keep in mind that Vystem hasn't been tested on real hardware yet, so the only way to test it is through a virtual machine. +You should have cloned the full repository on your device. You can uses Vystem in two cases: +- in a VM +- on a real computer -Vystem has been designed to be build and run from a standard Linux system. Any Linux distro should work. A WSL environnement can also work but the VM might be very slow, because of KVM unavailability. Make sure you have KVM enable and accessible before starting, or else remove the `--enable-kvm` argument at the end of the build script. +In both cases, Vystem has been designed to be build and run from a standard Linux system. Any Linux distro should work. A WSL environnement can also work but, if you are testing in a VM, the VM might be very slow or unstable in the benchmark results, because of KVM unavailability. Make sure you have KVM enable and accessible before starting, or else remove the `-accel kvm` argument at the end of the `build.json` file. Before starting, please make sure that you have the following binary reachable in your terminal path: ``` -python3 python nasm g++ gcc iasl git make sed wget unzip fallocate parted mkfs.fat sgdisk partprobe losesetup qemu-system-x86_64 +python3 python nasm g++ gcc iasl git make unzip ``` -Finally, please make sure that you have an internet connexion (required for downloading additionnal assets like EDK II and Argon2) as well as root access/sudo permissions, as it is recommanded for running `keygen` and required for creating the disk image. Root permissions is only obtained as soon as it's needed. If you don't want to give root permissions, you can also run the commands inside the build script one by one just to be sure. +You may also want `qemu-system-x86_64` if you are testing Vystem in a VM. + +Finally, please make sure that you have an internet connexion if EDK II isn't yet setuped as well as root access/sudo permissions, as it is necessary for running `keygen`. Root permissions is only obtained as soon as it's needed. ## Build and run Once you are ready, run the following command while being in the root folder: ``` bash -./build.sh +vybuild/build.sh ``` -This will download, compile, and assemble every asset together. This can take a while depending on your internet connexion, since EDK II is quite heavy and will be downloaded from it's source repository and locally compiled, with OVMF. For the moment, using packaged versions of EDK II and/or OVMF provided by packages managers isn't supported. +This script is designed to be used only from the root folder. + +This will build the `vybuild` executable inside the `vybuild` folder. This part isn't multithreaded and can take up to a whole minute depending on your device. + +Then, to start the build process, you can start VyBuild on the `build.json` file in the root folder like this: +``` bash +vybuild/vybuild build.json +``` + +This will compile, assemble and generate every asset together. This can take a while depending on your internet connexion, since EDK II is quite heavy and will be downloaded from it's source repository and locally compiled, with OVMF. For the moment, using packaged versions of EDK II and/or OVMF provided by packages managers isn't supported. The VM will automatically be launched with 4 gigabytes of RAM (you can obviously raise or lower that amount depending on your device), KVM enabled and serial port output redirected inside the terminal. -## Detailled build process +To generate the disk image without starting the VM, you can use the following command: +``` bash +vybuild/vybuild build.json img +``` -The folder used for InitFS base is named `initfs_dir` and is placed in the root folder of the repository. -The build process is as follow: -1) Checking virtual memory layout -2) Generating payloads for TAB subsystem -3) Compiling Keycard and putting it into `initfs_dir` -4) Compiling Vyld -5) Compiling Shelter and putting it into `initfs_dir` -6) Cloning EDK II, building required tools and OVMF -7) Compiling `bootanim` and generating boot animation -8) Compiling `fontgen` and generating font -9) Compiling `initfsgen` and generating InitFS and SignSyst -10) Patching bootloader configuration template to insert random partition GUID and fixed partition type GUID -11) Cloning and building Argon2, compiling `keygen` and generating required files for SPFIE -12) Compiling bootloader -13) Generating disk image -14) Launching virtual machine +Then, just flash the generated disk image on a USB disk and boot from it on real hardware. + +**Warning:** depending the properties of the firmware and available video cards on the hardware used to test Vystem, the EFI GOP framebuffer might not survive after ExitBootServices. ## Troubleshooting -If anything goes wrong, the script will stop and show you the error. Sometimes it's just a dependency that isn't reachable. Carefully analyse the error message and try to install the missing dependencies, also check that the required dependencies listed above are all installed. +If anything goes wrong, VyBuild will stop and show you the error. Sometimes it's just a dependency that isn't reachable. Carefully analyse the error message and try to install the missing dependencies, also check that the required dependencies listed above are all installed. If it's related to EDK II (which occur the majority of the time), it could be that a new update in EDK II has broken something. Don't hesitate to open an issue, and this should be fix fairly quickly. diff --git a/docs/commonlib.md b/docs/commonlib.md new file mode 100644 index 0000000..9f1d406 --- /dev/null +++ b/docs/commonlib.md @@ -0,0 +1,9 @@ +# Commonlib + +## Introduction + +Commonlib is a very simple C library that contains informations useful to all parts of Vystem. All the source code of Commonlib is stored inside the `common` folder. + +## Versions + +The header `versions.h` defines the versions number of various Vystem components. diff --git a/docs/index.md b/docs/index.md index 4506b69..b393cc3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # Vystem Docs -**Warning:** this documentation only include currently implemented elements and doesn't include plannned future elements, except some confirmed planned updates scattered within the documentation +**Warning:** this documentation only includes currently implemented elements and doesn't include plannned future elements, except some confirmed planned updates scattered within the documentation ## Introduction @@ -11,9 +11,11 @@ Welcome to Vystem documentation. This documentation is divided into severals par Vystem is an OS made of severals components which can be divided into severals categories: 1) [Blastproof](blastproof/index.md): the bootloader 2) [Bootloader tools](boottools/index.md): all the tools needed to generate components for the boot process -3) [Vyld](vyld/index.md): the VYX executable format linker and VYX executable format specification -4) [Shelter](shelter/index.md): the kernel -5) [Kernel tools](kerneltools/index.md): all the `.py` scripts used for various usage around the kernel +3) [Vyx](vyx.md): Vystem Executable format +4) [VyBuild](vybuild/index.md): Vystem build system +5) [Commonlib](commonlib.md): very simple library that contains informations useful to all parts of Vystem +6) [Shelter](shelter/index.md): the kernel +7) [Kernel tools](kerneltools/index.md): all the `.py` scripts used for various usage around the kernel ## Ressources diff --git a/docs/licenses.md b/docs/licenses.md index 50ee858..515bc0c 100644 --- a/docs/licenses.md +++ b/docs/licenses.md @@ -21,6 +21,7 @@ Original source code | Author | License [P-H-C/phc-winner-argon2](https://github.com/P-H-C/phc-winner-argon2) | Argon2 team | CC0-1.0 [tianocore/edk2](https://github.com/tianocore/edk2) | Tianocore and all the contributing companies | BSD-2-Clause-Patent [serge1/ELFIO](https://github.com/serge1/ELFIO) | Serge Lamikhov-Center | MIT +[nlohmann/json](https://github.com/nlohmann/json) | Niels Lohmann | MIT EDK II copyright: Copyright (c) Intel Corporation and other contributors. diff --git a/docs/roadmap.md b/docs/roadmap.md index d644439..9883ee6 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,13 +1,60 @@ # Roadmap -## Version 0.1 (actual) +## Version 0.1 (previous) Initial release -## Version 0.2 (future versions with planned additions) +## Version 0.2 (actual) -- Vyld overhaul, support for multiples compilations modes with JSON config files for project settings -- VYX format overhaul, supporting various sections and more feature -- Blastproof: custom keyboard layout driver -- Shelter: Support for IDT, GDT, TSS, interruptions, interruptions handler, ACPI timers table parsing and ACPI driver -- Shelter: Slab allocators overhaul and performance boosts +- Blastproof: + - New boot password screen, with power options + - Support for custom keyboard layouts using correspondance tables + - Config is now stored in .cfg files + - VFTM support + - Partition tables is now parsed without relying on UEFI firmware + - New configuration key: `kernel_kbd_events_queue_capacity` +- Vyx: + - Support for payloads with custom mappings options +- Initfsgen: + - The `initfs-footprint.bin` file is now named `initfsfp.bin` + - The `signsyst-hash.bin` file is now named `sshash.bin` +- Keygen: + - Removed layout conversion feature + - The utility will now check if a password is provided in the `VYSTEM_KEYGEN_PASSWORD` environnement variable + - The manual password setup will still be proposed if `VYSTEM_KEYGEN_PASSWORD` isn't defined or is empty + - This method of inputing password via `VYSTEM_KEYGEN_PASSWORD` should ONLY be used in a developpement environnement + - Keygen now generate root and manifest keypairs, and expect a `vftm.sock` UNIX socket to transmit manifest keypair to a compatible build system +- VyBuild: + - A new build system, see documentation for more informations +- Commoncrypto: + - A new library made of three cryptographic libraries, required for Keygen, Initfsgen and VyBuild +- Vystem FAT Trusted Manifest: + - A new signed manifest, injected inside the reserved sectors of the ESP partition FAT32 + - It's signed using a combinaison of Keygen and VyBuild + - It allow to verify the link between ESP partition and current disk, as well as FAT32 integrity and self bootloader verification +- Common Lib: + - In the `common` folder, new headers that will be accessible to all components of Vystem will be put here + - For the moment, it only includes the reference version of each component +- Shelter: + - Can now manage TSS, GDT and IDT + - Can now parse root ACPI table and MADT + - Can now interact with LAPIC, estimating CPU and LAPIC frequency + - Can now start APs + - Can now manages IOAPIC devices and GSI lines as well as legacy IRQs + - Added thread safety to print, timers and malloc. Added iprint/iprintf/sprintf. + - Added Device System, endpoints from APIC, TSC, kernel configuration, memory and SMP subsystem are available + - Device System is not available for the input subsystem yet, as it would requires Ring 3 architecture, that isn't ready for now + - Add very basic framebuffer support for early kernel progress bar +- Image build processus: + - The signatures are now stored as `.sig` files + - The signatures are now stored inside `EFI/BPSIGN` folder + - The bootloader files are now stored inside `EFI/BPFILES` folder + +## Version 0.3 (future release with planned additions) + +- Updated `SH_STATUS` struct +- New Modular Daemon Unit with the first type being implemented: kernel library. Run in ring 3 with very basic API +- First features of the VFS, with InitFS drivers +- MCFG ACPI table parsing, PCIe devices enumeration, first MSI/MSI-X implementation +- SATA driver, volumes enumeration with integration to the VFS +- Upgrade to the Device System, with new APIs for the input subsystem and VFS, as well as Device System querying through the VFS diff --git a/docs/shelter/bench.md b/docs/shelter/bench.md index c2a616f..3864cd3 100644 --- a/docs/shelter/bench.md +++ b/docs/shelter/bench.md @@ -5,10 +5,10 @@ In this file, you will be able to see examples of benchmark results. These are p ## Tests environnement - Host OS: EndeavourOS x86_64 -- Host kernel: Linux 6.19.10-arch1-1 +- Host kernel: Linux 7.0.10-arch1-1 - Host CPU: Ryzen 7 9800x3d @ 5.27 GHz -- Environnement: VM running in qemu-system-x86_64 version 10.2.2 -- VM parameters: KVM enabled, 4096M of RAM, cpu set to host, running in single thread +- Environnement: VM running in qemu-system-x86_64 version 11.0.0 +- VM parameters: KVM enabled, 4096M of RAM, cpu set to host The following tests are shown in the order the kernel run them. Please keep in mind that Pez isn't available until the Pez physical plane benchmark. @@ -17,31 +17,31 @@ The following tests are shown in the order the kernel run them. Please keep in m Physical regions object slab allocator: ``` Result for benchmark "allocations" : -Min: 141 | Med: 235 | Avg: 2736 | Max: 3194120 | Total : 27362977 (TSC) -[P00-P90] 141-282 : [##################--] 90% -[P90-P99] 282-282 : [#-------------------] 9% -[P99-Max] 282-3194120 : [--------------------] 1% +Min: 141 | Med: 235 | Avg: 3051 | Max: 3175320 | Total : 30517523 (TSC) +[P00-P90] 141-235 : [##################--] 90% +[P90-P99] 235-282 : [#-------------------] 9% +[P99-Max] 282-3175320 : [--------------------] 1% Result for benchmark "deallocations" : -Min: 94 | Med: 141 | Avg: 132 | Max: 376 | Total : 1320700 (TSC) +Min: 94 | Med: 141 | Avg: 131 | Max: 611 | Total : 1313415 (TSC) [P00-P90] 94-141 : [##################--] 90% [P90-P99] 141-141 : [#-------------------] 9% -[P99-Max] 141-376 : [--------------------] 1% +[P99-Max] 141-611 : [--------------------] 1% ``` Virtual regions object slab allocator: ``` Result for benchmark "allocations" : -Min: 141 | Med: 235 | Avg: 2781 | Max: 2840445 | Total : 27816339 (TSC) -[P00-P90] 141-282 : [##################--] 90% -[P90-P99] 282-329 : [#-------------------] 9% -[P99-Max] 329-2840445 : [--------------------] 1% +Min: 141 | Med: 235 | Avg: 3051 | Max: 3175320 | Total : 30517523 (TSC) +[P00-P90] 141-235 : [##################--] 90% +[P90-P99] 235-282 : [#-------------------] 9% +[P99-Max] 282-3175320 : [--------------------] 1% Result for benchmark "deallocations" : -Min: 94 | Med: 141 | Avg: 130 | Max: 517 | Total : 1304109 (TSC) +Min: 94 | Med: 141 | Avg: 131 | Max: 611 | Total : 1313415 (TSC) [P00-P90] 94-141 : [##################--] 90% [P90-P99] 141-141 : [#-------------------] 9% -[P99-Max] 141-517 : [--------------------] 1% +[P99-Max] 141-611 : [--------------------] 1% ``` ## Results for radix node slab allocator (PBA based) @@ -49,16 +49,16 @@ Min: 94 | Med: 141 | Avg: 130 | Max: 517 | Total : 1304109 (TSC) Radix node slab allocator (PBA based): ``` Result for benchmark "allocations" : -Min: 141 | Med: 188 | Avg: 441 | Max: 534531 | Total : 4410339 (TSC) +Min: 141 | Med: 235 | Avg: 426 | Max: 624395 | Total : 4264498 (TSC) [P00-P90] 141-235 : [##################--] 90% [P90-P99] 235-282 : [#-------------------] 9% -[P99-Max] 282-534531 : [--------------------] 1% +[P99-Max] 282-624395 : [--------------------] 1% Result for benchmark "deallocations" : -Min: 94 | Med: 94 | Avg: 97 | Max: 329 | Total : 973370 (TSC) +Min: 94 | Med: 94 | Avg: 95 | Max: 611 | Total : 954664 (TSC) [P00-P90] 94-94 : [##################--] 90% [P90-P99] 94-141 : [#-------------------] 9% -[P99-Max] 141-329 : [--------------------] 1% +[P99-Max] 141-611 : [--------------------] 1% ``` ## Results for radix trees subsystem @@ -66,28 +66,28 @@ Min: 94 | Med: 94 | Avg: 97 | Max: 329 | Total : 973370 (TSC) Radix trees subsystem: ``` Result for benchmark "insertions into radix trees" : -Min: 2350 | Med: 3196 | Avg: 5194 | Max: 544448 | Total : 51944259 (TSC) -[P00-P90] 2350-3666 : [##################--] 90% -[P90-P99] 3666-134373 : [#-------------------] 9% -[P99-Max] 134373-544448 : [--------------------] 1% +Min: 2350 | Med: 3196 | Avg: 5364 | Max: 668575 | Total : 53644531 (TSC) +[P00-P90] 2350-3713 : [##################--] 90% +[P90-P99] 3713-134608 : [#-------------------] 9% +[P99-Max] 134608-668575 : [--------------------] 1% Result for benchmark "reading into radix trees" : -Min: 470 | Med: 517 | Avg: 553 | Max: 31631 | Total : 5537399 (TSC) +Min: 470 | Med: 517 | Avg: 543 | Max: 22466 | Total : 5432213 (TSC) [P00-P90] 470-564 : [##################--] 90% -[P90-P99] 564-987 : [#-------------------] 9% -[P99-Max] 987-31631 : [--------------------] 1% +[P90-P99] 564-658 : [#-------------------] 9% +[P99-Max] 658-22466 : [--------------------] 1% Result for benchmark "searching value with lower bound key" : -Min: 423 | Med: 893 | Avg: 923 | Max: 30832 | Total : 9234184 (TSC) -[P00-P90] 423-1128 : [##################--] 90% -[P90-P99] 1128-1645 : [#-------------------] 9% -[P99-Max] 1645-30832 : [--------------------] 1% +Min: 470 | Med: 846 | Avg: 902 | Max: 156134 | Total : 9021368 (TSC) +[P00-P90] 470-1081 : [##################--] 90% +[P90-P99] 1081-1363 : [#-------------------] 9% +[P99-Max] 1363-156134 : [--------------------] 1% Result for benchmark "deleting values" : -Min: 1645 | Med: 1880 | Avg: 1888 | Max: 35203 | Total : 18889770 (TSC) -[P00-P90] 1645-2021 : [##################--] 90% -[P90-P99] 2021-2162 : [#-------------------] 9% -[P99-Max] 2162-35203 : [--------------------] 1% +Min: 1598 | Med: 1833 | Avg: 1860 | Max: 33276 | Total : 18607018 (TSC) +[P00-P90] 1598-1974 : [##################--] 90% +[P90-P99] 1974-2256 : [#-------------------] 9% +[P99-Max] 2256-33276 : [--------------------] 1% ``` ## Results for Pez physical plane @@ -95,55 +95,66 @@ Min: 1645 | Med: 1880 | Avg: 1888 | Max: 35203 | Total : 18889770 (TSC) Pez physical plane: ``` Result for benchmark "allocations for single page" : -Min: 1833 | Med: 2444 | Avg: 3496 | Max: 8225 | Total : 3496518 (TSC) -[P00-P90] 1833-5922 : [##################--] 90% -[P90-P99] 5922-6815 : [#-------------------] 9% -[P99-Max] 6815-8225 : [--------------------] 1% +Min: 1786 | Med: 2444 | Avg: 3348 | Max: 6862 | Total : 3348656 (TSC) +[P00-P90] 1786-5593 : [##################--] 90% +[P90-P99] 5593-6721 : [#-------------------] 9% +[P99-Max] 6721-6862 : [--------------------] 1% Result for benchmark "free for single page" : -Min: 1974 | Med: 2820 | Avg: 3807 | Max: 10105 | Total : 3807376 (TSC) -[P00-P90] 1974-6862 : [##################--] 90% -[P90-P99] 6862-8131 : [#-------------------] 9% -[P99-Max] 8131-10105 : [--------------------] 1% +Min: 1927 | Med: 2820 | Avg: 3840 | Max: 33981 | Total : 3840417 (TSC) +[P00-P90] 1927-6721 : [##################--] 90% +[P90-P99] 6721-8037 : [#-------------------] 9% +[P99-Max] 8037-33981 : [--------------------] 1% Result for benchmark "allocations for multiple pages" : -Min: 2209 | Med: 5593 | Avg: 5716 | Max: 35861 | Total : 5716798 (TSC) -[P00-P90] 2209-7191 : [##################--] 90% -[P90-P99] 7191-8178 : [#-------------------] 9% -[P99-Max] 8178-35861 : [--------------------] 1% +Min: 2303 | Med: 5405 | Avg: 5568 | Max: 33793 | Total : 5568231 (TSC) +[P00-P90] 2303-7050 : [##################--] 90% +[P90-P99] 7050-8131 : [#-------------------] 9% +[P99-Max] 8131-33793 : [--------------------] 1% Result for benchmark "free for multiple pages" : -Min: 1927 | Med: 4935 | Avg: 5095 | Max: 31772 | Total : 5095599 (TSC) -[P00-P90] 1927-7896 : [##################--] 90% -[P90-P99] 7896-10011 : [#-------------------] 9% -[P99-Max] 10011-31772 : [--------------------] 1% +Min: 2115 | Med: 4841 | Avg: 5066 | Max: 29892 | Total : 5066506 (TSC) +[P00-P90] 2115-7849 : [##################--] 90% +[P90-P99] 7849-9635 : [#-------------------] 9% +[P99-Max] 9635-29892 : [--------------------] 1% ``` ## Results for malloc subsystem Malloc subsystem: ``` -Result for benchmark "sh_malloc for small size" : -Min: 188 | Med: 423 | Avg: 535 | Max: 380277 | Total : 5358752 (TSC) -[P00-P90] 188-799 : [##################--] 90% -[P90-P99] 799-1363 : [#-------------------] 9% -[P99-Max] 1363-380277 : [--------------------] 1% +Result for benchmark "allocations for single page" : +Min: 1786 | Med: 2444 | Avg: 3348 | Max: 6862 | Total : 3348656 (TSC) +[P00-P90] 1786-5593 : [##################--] 90% +[P90-P99] 5593-6721 : [#-------------------] 9% +[P99-Max] 6721-6862 : [--------------------] 1% -Result for benchmark "sh_free for small size" : -Min: 141 | Med: 329 | Avg: 403 | Max: 27401 | Total : 4039556 (TSC) -[P00-P90] 141-658 : [##################--] 90% -[P90-P99] 658-1128 : [#-------------------] 9% -[P99-Max] 1128-27401 : [--------------------] 1% +Result for benchmark "free for single page" : +Min: 1927 | Med: 2820 | Avg: 3840 | Max: 33981 | Total : 3840417 (TSC) +[P00-P90] 1927-6721 : [##################--] 90% +[P90-P99] 6721-8037 : [#-------------------] 9% +[P99-Max] 8037-33981 : [--------------------] 1% -Result for benchmark "sh_malloc for pages allocations" : -Min: 4935 | Med: 11468 | Avg: 11890 | Max: 47893 | Total : 11890013 (TSC) -[P00-P90] 4935-16450 : [##################--] 90% -[P90-P99] 16450-20257 : [#-------------------] 9% -[P99-Max] 20257-47893 : [--------------------] 1% +Result for benchmark "allocations for multiple pages" : +Min: 2303 | Med: 5405 | Avg: 5568 | Max: 33793 | Total : 5568231 (TSC) +[P00-P90] 2303-7050 : [##################--] 90% +[P90-P99] 7050-8131 : [#-------------------] 9% +[P99-Max] 8131-33793 : [--------------------] 1% -Result for benchmark "sh_free for pages allocations" : -Min: 5593 | Med: 11421 | Avg: 12005 | Max: 50760 | Total : 12005398 (TSC) -[P00-P90] 5593-17296 : [##################--] 90% -[P90-P99] 17296-21432 : [#-------------------] 9% -[P99-Max] 21432-50760 : [--------------------] 1% +Result for benchmark "free for multiple pages" : +Min: 2115 | Med: 4841 | Avg: 5066 | Max: 29892 | Total : 5066506 (TSC) +[P00-P90] 2115-7849 : [##################--] 90% +[P90-P99] 7849-9635 : [#-------------------] 9% +[P99-Max] 9635-29892 : [--------------------] 1% +``` + +## Results for queues + +Keyboard events queue: +``` +Result for benchmark "pushing objects" : +Min: 141 | Med: 141 | Avg: 221 | Max: 546892 | Total : 2215580 (TSC) +[P00-P90] 141-188 : [##################--] 90% +[P90-P99] 188-235 : [#-------------------] 9% +[P99-Max] 235-546892 : [--------------------] 1% ``` diff --git a/docs/shelter/bootconfig.md b/docs/shelter/bootconfig.md index 3e3f3a9..556995d 100644 --- a/docs/shelter/bootconfig.md +++ b/docs/shelter/bootconfig.md @@ -19,6 +19,10 @@ typedef struct __attribute__((aligned(8))) { sh_bool log_disable_serial_port; sh_bool disable_serial_port; sh_uint16 log_ring_size; + sh_uint64 acpi_rsdp; + sh_uint8 acpi_ver; + sh_uint16 kbd_events_queue_capacity; + sh_conf_FB_CONFIG fb_config; sh_uint8 sig_end[8]; } sh_conf_BOOT_CONFIG; ``` @@ -62,3 +66,40 @@ The starting signature must be `ShCfgBeg` in ASCII and the starting signature mu **log_ring_size:** - Type: 2 bytes unsigned integer - Description: define the amount of pages used for logging ring buffer + +**acpi_rsdp:** +- Type: 8 bytes unsigned integer +- Description: the physical address of the ACPI RDSP + +**acpi_ver:** +- Type: 1 byte unsigned integer +- Description: define the version of ACPI provided by the firmware, can be 1 or 2 depending on the ACPI version GUID found by Blastproof + +**kbd_events_queue_capacity:** +- Type: 2 bytes unsigned integer +- Description: the capacity of each keyboard events queue. The value of this key is provided by the `kernel_kbd_events_queue_capacity` from the Blastproof boot config + +**fb_config:** +- Type: custom struct +- Description: informations on the early boot framebuffer, intended to work with GOP framebuffer information + +## FB config structure + +The `fb_config` structure is defined like that: +``` C +typedef struct __attribute__((aligned(8))) { + sh_bool fb_present; + sh_page_VIRTUAL_ADDRESS fb_pa; + sh_uint32 white_pixel_value; + sh_uint32 gray_pixel_value; + sh_uint64 size_in_bytes; + sh_uint32 fb_height; + sh_uint32 fb_width; + sh_uint16 text_x; + sh_uint16 text_y; + sh_uint16 text_width; + sh_uint16 text_height; +} sh_conf_FB_CONFIG; +``` + +The `fb_present` field should be set to `false` if anything impeach the framebuffer to be fully operational. The `fb_pa` field is the physical address of the framebuffer. The kernel will map the framebuffer itself. The `white_pixel_value` and `gray_pixel_value` contain the encoded pixel data for the color white and gray. The `text_x`, `text_y`, `text_width` and `text_height` serve the purpose of defining an area that the kernel should erase before starting using the progress bar. They are named like that because most of the time, it will be a text placed by the bootloader that the kernel should erase. Others fields are self-explenatory. diff --git a/docs/shelter/bootcontract.md b/docs/shelter/bootcontract.md index 9bc0b5e..d57c03c 100644 --- a/docs/shelter/bootcontract.md +++ b/docs/shelter/bootcontract.md @@ -11,7 +11,7 @@ We assume the following: - you have a bootloader capable of mapping things into into pages table pool - your bootloader is capable of generating Shelter boot configuration and Shelter memory map - your bootloader is capable of allocating or call the UEFI firmware to allocates pages to copy data into them -- your bootloader is capable of parsing VYX executable +- your bootloader is capable of parsing VYX executable, including payloads - your bootloader is capable of accessing the content of the Shelter VYX executable and keycard binary While this documentation is redacted like a tutorial, this isn't a tutorial nor intended to be understand as one. @@ -24,6 +24,7 @@ Your bootloader should be allocating 4KB physical pages ranges and store their p - page(s) for keycard should be `EfiLoaderCode` type. Keycard should fit into one page, but you are free to allocate more if you want - page(s) for Shelter boot configuration, memory map and pages table pool should be `EfiLoaderCode`. Shelter boot configuration should fit into one page, but you are free to allocate more if you want - pages for Shelter logging ring should be `EfiLoaderCode` type +- pages for Shelter VYX binary payloads should be `EfiLoaderCode` type or `EfiLoaderData` type depending on the type of payload Note: even if the logging ring size specified in the configuration is less than 4 pages, at least 4 pages should be allocated, because the kernel logs some things before loading the boot configuration that specify that log in ring buffer is disabled @@ -37,6 +38,7 @@ The following steps should be completed before mapping the pages: - copying the content of the `.text`, `.data` and `.rodata` section inside their respectives pages range - copying the content of Keycard inside his pages range - copying the content of the boot configuration inside his pages range +- parsing the VYX binary for payloads, allocating pages for them, zeroing those pages and copying the content of each payload into their respectives pages ## Step 3: mapping pages @@ -52,6 +54,7 @@ The following pages ranges will be mapped at the following virtual address in th - Shelter boot configuration pages should be mapped at VA `0x00180000`, with no execution and read-write permissions - memory map pages should be mapped at VA `0x00190000`, with no execution and read-only permissions - logging ring pages should be mapped at VA `0xFFFFFFFFF0000000`, with no execution and read-write permissions +- each payload should be mapped at the indicated VA, with the indicated permissions ## Step 4: completing configuration diff --git a/docs/shelter/bootprocess.md b/docs/shelter/bootprocess.md index 837a14e..abf6a14 100644 --- a/docs/shelter/bootprocess.md +++ b/docs/shelter/bootprocess.md @@ -34,7 +34,9 @@ Starting here, all logs go through the standard log API. 2.1.2) Initializing current PTP using boot configuration information -2.1.3) Parsing and validating memory map, initializing physical pages bitmap +2.1.3) Using the framebuffer informations, initializing the framebuffer subsystem + +2.1.4) Parsing and validating memory map, initializing physical pages bitmap ### 2.2) Pez dependencies subsystems initialization @@ -62,19 +64,19 @@ Starting here, all logs go through the standard log API. 2.2.5) Benchmarking and testing radix tree subsystem -## 2.3) Pez physical subsystem initialization +### 2.3) Pez physical subsystem initialization 2.3.1) Creating Pez physical allocation plane 2.3.2) Benchmarking and testing Pez physical allocation plane -## 2.4) Pez virtual subsystem initialization +### 2.4) Pez virtual subsystem initialization 2.4.1) Creating Pez virtual allocation plane for kernel heap (Pez virtual plane for kernel heap isn't benchmarked and tested because it's exactly the same algorithm and metadatas under the hood) -## 2.5) Kernel heap initialization +### 2.5) Kernel heap initialization 2.5.1) Initializing kernel heap structure @@ -87,3 +89,89 @@ Starting here, all logs go through the standard log API. 2.5.2.c) Adding first slab and verifying slab metadata 2.5.3) Benchmarking and testing kernel heap + +## 3) Basic CPU features configuration + +### 3.1) TSS structure initialization + +3.1.1) Initializing TSS structure + +### 3.2) GDT structure initialization + +3.2.1) Generating GDT structure + +3.2.2) Loading GDT register + +3.2.3) Loading TSS register + +### 3.3) IDT structure initialization + +3.3.1) Generating IDT structure + +3.3.2) Loading IDT register + +## 4) ACPI parsing + +### 4.1) Parsing RSDP + +### 4.2) Parsing XSDT + +### 4.3) Parsing all availables tables + +### 4.4) Parsing MADT table + +4.4.1) Counting all LAPICs, IOAPICs and ISOs + +4.4.2) Initializing devices system for LAPICs and IOAPICs + +4.4.3) Registering all informations inside MADT table + +4.4.3.a) Registering, initializing and binding all LAPICs + +4.4.3.b) Registering, initializing and binding all IOAPICs + +4.4.3.c) Registering all ISOs + +## 5) Devices bootstrap + +### 5.1) Applications= processors (AP) bootstrap + +5.1.1) Disabing all GSI lines + +5.1.2) Checking somes CPU ID flags for logging + +5.1.2.a) Checking hypervisor flag + +5.1.2.b) Checking TSC constant flag + +5.1.3) Trying to obtain CPU frequency + +5.1.3.a) Trying to obtain CPU frequency from CPU ID + +5.1.3.b) Trying to obtain CPU frequency from TSC and PIT + +5.1.4) Initializing LAPIC for bootstrap CPU + +5.1.5) Estimating LAPIC frequency + +5.1.6) Loading 32 bits mode GDT for AP bootstrap + +5.1.7) Preparing for AP launch by filling various structures + +5.1.8) Launching all APs in an infinite loop + +--- + +Starting here, all logs go through the standard library print functions. + +--- + +5.1.9) Switching legacy IRQ management from PIT to IOAPIC subsystem + +### 5.2) Keyboard bootstrap + +5.2.1) Initializing keyboard subsystem + +5.2.2) Initializing PS2 keyboard driver + +5.2.3) Disabing PS2 keyboard scanning for the rest of kernel boot process diff --git a/docs/shelter/cpu/ap.md b/docs/shelter/cpu/ap.md new file mode 100644 index 0000000..ffc7509 --- /dev/null +++ b/docs/shelter/cpu/ap.md @@ -0,0 +1,116 @@ +# Application Processors subsystem + +## Introduction + +The Application Processors (AP) subsystem is responsible for managing SMP-related CPU abstractions, including CPU descriptors and per-CPU data structures. It also handles the preparation and bootstrap sequence required to bring up secondary processors. This subsystem is defined inside `shelter/lib/include/cpu/ap.h` and implemented inside `shelter/lib/include/cpu/ap.c`. + +## Overview + +This subsystem is responsible for three things: +- defining the structures used to describe CPUs and storing per-CPU metadatas +- preparing all necessary structures in order to start the APs +- starting the APs + +### CPU structures + +The AP subsystem defines two structures related to CPU metadatas: + +**`sh_ap_CPU_STRUCT`:** + +``` C +#pragma pack(1) +typedef struct { + sh_page_VIRTUAL_ADDRESS c_entry_point_stack_top_va; + sh_uint32 lapic_id; + sh_uint16 tss_selector; + sh_ap_PER_CPU *per_cpu; +} sh_ap_CPU_STRUCT; +#pragma pack() +``` + +The CPU struct is mainly used for the AP trampoline: it contain informations specific to each AP that will allow them to reach the C entry point. It also contains a pointer to the per-CPU struct of each CPU. + +**`sh_ap_PER_CPU`:** + +``` C +#pragma pack(1) +typedef struct { + sh_uint64 cpu_id; + sh_uint32 bytes_outputed; + sh_bool timer_state; + char *temp_buffer; + sh_uint64 temp_buffer_size; +} sh_ap_PER_CPU; +#pragma pack() +``` + +The per-CPU struct is used for per-CPU metadatas like LAPIC timer state, per-CPU temporary buffer, logical CPU id and various per-CPU metadatas for differents kernel subsystems. + +The logical CPU id is an id assigned to each processor. The bootstrap processor always obtain the id 0, and there is no gap in the logical CPU id allocation space. It allow for an alternative to LAPIC ids and ACPI processors id, which can contain gaps in their allocation space. + +The GS base register of each AP contain a pointer to the CPU struct of each AP. The CPU and per-CPU struct of the bootstrap processor is created at the start of the kernel entry point and then elaborated during the AP bootstrap procedure. It isn't stored inside the AP's CPU struct array. + +### Preparing all necessary structures for AP bootstrap + +Since all APs start in 16 bits mode, Shelter uses the following **physical** address to put importants compoments there: +- `0x7000`: the physical address of the AP trampoline, shared by all APs +- `0x8000`: the physical address of the 32 bits GDT, necessary for the 32 bits far jump +- `0x9000`: the physical address of the AP bootstrap struct + +All those addresses are identity mapped in the bootstrap CPU page table. Additionally, the AP trampoline loaded from the VYX binary of Shelter is mapped at the virtual address `0xA000`. + +The AP bootstrap struct is a structure that contains all commons addresses used by all APs: + +``` C +#pragma pack(1) +typedef struct { + sh_page_PHYSICAL_ADDRESS lapic_base_pa; + sh_page_VIRTUAL_ADDRESS c_entry_point_va; + sh_page_PHYSICAL_ADDRESS page_table_pa; + sh_page_VIRTUAL_ADDRESS cpu_struct_base_area; + sh_page_VIRTUAL_ADDRESS shared_gdt_64_va; + sh_gdt_GDTR gdt_64_gdtr; + sh_idt_IDT *idt; +} sh_ap_AP_BOOTSTRAP; +#pragma pack() +``` + +It contain things such as the LAPIC memory mapped area PA, the C entry point VA, the page table PA, the CPU struct array VA, the shared GDT VA for the 64 bits far jump, the GDTR for the said GDT and the IDT VA. + +During the kernel boot process, all APs share the same page table as the bootstrap processor for simplicity. + +First, the 32 bits GDT is generated and placed at PA `0x8000` by `sh_ap_load_gdt_32()`. Then the rest of the AP bootstrap preparation is handled by `sh_ap_prepare_for_smp_launch()` + +Here is the detailled processus: +1) Identity-mapping the page at PA `0x9000` to initialize obvious values like C entry point VA, page table PA and LAPIC base PA. +2) Allocating the array of CPU struct on the heap (indexed by LAPIC id), and initializing the corresponding value in the AP bootstrap struct. +3) Allocating the array of TSS on the heap. +4) Looping on all availables LAPIC to fill all CPU struct: allocating the stack for each AP, filling the LAPIC id, filling the TSS of each AP, allocating the multiple stacks for each TSS, filling the per-CPU struct of each AP. +5) Filling the global GDT for all APs with all TSS, completing the AP bootstrap struct, initializing the AP start state. + +### Starting the APs + +Once everything is ready, `sh_ap_start_ap_boot_procedure()` is called once to start all APs. The procedure is as follow: +1) Copying the AP trampoline from VA `0xA000` to VA/PA `0x7000`. +2) Filling CPU struct and per-CPU struct of the bootstrap CPU. +3) Sending INIT IPI and waiting 10 millisecond. +4) Sending SIPI and waiting for all APs to start. At this point, the `sh_print` standard library feature is ready. + +All APs will start in 16 bits mode and execute the following sequence of action: +1) Disabling interrupts +2) Load 32 bits GDT, enabling 32 bits mode in CR0 and executing the far jump to get to 32 bits mode +3) Reading LAPIC base, extracting LAPIC id and keeping it in a register +4) Enabling PAE, loading page table PA into CR3, enabling LME and NXE bits +5) Enabling pagging, and executing the far jump to get to 64 bits mode +6) Locating the CPU struct for this CPU using the CPU LAPIC id +7) Loading the local CPU stack +8) Loading 64 bits shared GDT, reloading CS register +9) Loading task register and GS register +10) Jumping to C entry point + +The C entry point is the function named `sh_ap_entry_point()`. It does the following things: +1) Initialize the LAPIC of the AP +2) Load the shared IDT +3) Confirm to the bootstrap CPU that everything is ready for this AP by updating the corresponding AP start state and goes into an infinite loop + +If the bootstrap CPU doesn't receives any confirmation from one of the AP, the boot process is halted. diff --git a/docs/shelter/cpu/asmint.md b/docs/shelter/cpu/asmint.md index 9edfbf6..e805def 100644 --- a/docs/shelter/cpu/asmint.md +++ b/docs/shelter/cpu/asmint.md @@ -11,3 +11,12 @@ Here is a list of all the wrappers available. They are all defined as `static in - `outb`: take a `sh_uint16` for specifying the port and a `sh_uint8` for specifying the byte to output - `rdtsc`: take no arguments and return the current TSC as a `sh_uint64` - `invlpg`: take a `void *` as an address and return nothing +- `lgdt`: take a `void *` as an address and return nothing +- `ltr`: take a `sh_uint16` as a TSS selector and return nothing +- `sidt`: take a `sh_idt_IDTR*` as a pointer and return nothing +- `sti`: take no arguments and return nothing +- `cli`: take no arguments and return nothing +- `cpuid`: take 2 `sh_uint32`: `leaf`, `subleaf`, and 2 `sh_uint32*`: `eax`, `ebx`, `ecx`, `edx`, return nothing +- `mfence`: take no arguments and return nothing +- `lfence`: take no arguments and return nothing +- `sfence`: take no arguments and return nothing diff --git a/docs/shelter/cpu/cpuabstract.md b/docs/shelter/cpu/cpuabstract.md index e982ab2..fa2cf5f 100644 --- a/docs/shelter/cpu/cpuabstract.md +++ b/docs/shelter/cpu/cpuabstract.md @@ -9,3 +9,6 @@ This component of the Shelter kernel allow for basic CPU functions abstractions, 1) [ASM instructions](asmint.md) 2) [Serial outputing API](serial.md) 3) [TSC API](tsc.md) +4) [PIC API](pic.md) +5) [PIT API](pit.md) +6) [Application processors subsystem](ap.md) diff --git a/docs/shelter/cpu/pic.md b/docs/shelter/cpu/pic.md new file mode 100644 index 0000000..afd516c --- /dev/null +++ b/docs/shelter/cpu/pic.md @@ -0,0 +1,13 @@ +# PIC API + +## Introduction + +The PIC API is used to correctly setup the PIC, before the initialization of the IOAPIC subsystem. It provides a minimal API to manage only the part where the PIC is needed in the boot process. Otherwise, the PIC is just ignored once all legacy IRQs are managed by the IOAPIC subsystem. The PIC API is defined in `shelter/lib/include/cpu/pic.h` and implemented in `shelter/lib/include/cpu/pic.c`. + +## API overview + +The API provides the following functions: +- `sh_pic_remap()`: remap all legacy IRQs on IDT vectors 32 to 47, should only be called once before any use of the PIC +- `sh_pic_unmask()`: take an IRQ number and unmask this IRQ line +- `sh_pic_mask()`: take an IRQ number and mask this IRQ line +- `sh_pic_send_eoi()`: send End Of Interrupt signal to the PIC diff --git a/docs/shelter/cpu/pit.md b/docs/shelter/cpu/pit.md new file mode 100644 index 0000000..13d7bb0 --- /dev/null +++ b/docs/shelter/cpu/pit.md @@ -0,0 +1,6 @@ +# PIT API + +In Shelter, the PIT is only used for one purpose: estimating the CPU frequency. It's only used with the PIC, never with the IOAPIC, so the API is volontarily very simple: +- `sh_pit_set_frequency()`: expect the frequency as argument. Set the PIT to uses this frequency and return nothing + +This API is defined inside `shelter/lib/include/cpu/pit.h` and implemented inside `shelter/lib/include/cpu/pic.c`. diff --git a/docs/shelter/cpu/serial.md b/docs/shelter/cpu/serial.md index 05a0f1d..18a360d 100644 --- a/docs/shelter/cpu/serial.md +++ b/docs/shelter/cpu/serial.md @@ -2,7 +2,7 @@ ## Introduction -Shelter provide an abstraction around the serial port for outputing on it. This should act as the central point for outputing on the serial. The API is defined in `shelter/lib/include/cpu/serial.h` and implemented in `shelter/lib/src/cpu/serial.c`. This API obey the `serial_port_disabled` killswitch defined in kernel boot configuration. The subsystem prefix is `sh_serial_`. +Shelter provides an abstraction around the serial port for outputing on it. This should act as the central point for outputing on the serial. The API is defined in `shelter/lib/include/cpu/serial.h` and implemented in `shelter/lib/src/cpu/serial.c`. This API obey the `serial_port_disabled` killswitch defined in kernel boot configuration. The subsystem prefix is `sh_serial_`. ## Overview diff --git a/docs/shelter/cpu/tsc.md b/docs/shelter/cpu/tsc.md index 7d53ddd..97c7635 100644 --- a/docs/shelter/cpu/tsc.md +++ b/docs/shelter/cpu/tsc.md @@ -2,14 +2,16 @@ ## Introduction -In order to be able to measure and approximate time as soon as the kernel start the boot process, the TSC API is implemented in a volontary minimal way. The TSC API is defined inside `shelter/lib/include/cpu/tsc.h` and implemented inside `shelter/lib/src/cpu/tsc.c`. The API prefix is `sh_tsc_`. +In order to be able to measure and approximate time as soon as the kernel start the boot process, the TSC API is implemented in a volontarily minimal way. The TSC API is defined inside `shelter/lib/include/cpu/tsc.h` and implemented inside `shelter/lib/src/cpu/tsc.c`. The API prefix is `sh_tsc_`. ## Overview -The TSC API being intented for measuring time during the boot process, the provided features are extremely basic. In order for any TSC value to start at 0, we define two concept: +One of the TSC API goal being measuring time during the boot process, the provided features regarding this goal are extremely basic. In order for any TSC value to start at 0, we define two concept: - `kernel_init_tsc`: a TSC value initialized at the very start of the kernel boot process - `kernel_current_tsc`: a TSC value which is the result of `kernel_init_tsc` substracted to the value returned by `sh_asm_rdtsc()` +Starting with Shelter 0.2, the TSC API also provides primitives to estimate CPU frequency using PIT and TSC, or CPU ID if available. + ## API content The API define the following elements: @@ -18,3 +20,9 @@ The API define the following elements: - `sh_tsc_init_tsc()`: a function initializing `kernel_init_tsc`. This function should only be called once as soon as the kernel start. Return a `SH_STATUS` - `sh_tsc_get_kernel_init_tsc()`: return `kernel_init_tsc` under a `sh_tsc_TSC_VALUE` - `sh_tsc_get_kernel_current_tsc()`: return the result of `sh_asm_rdtsc()` less `kernel_init_tsc`, under a `sh_tsc_TSC_VALUE` +- `sh_tsc_estimate_cpu_freq()`: estimate CPU frequency using PIT and TSC, should only be called once the IDT has been initialized and PIT remapped on the correct IDT vector, and before the start of all APs. It return the estimated frequency under a `sh_uint64` +- `sh_tsc_load_cpu_freq()`: take a `sh_uint64` and load it as CPU frequency, return nothing +- `sh_tsc_has_hypervisor()`: return `SH_TRUE` if the hypervisor bit in CPU ID is set, take no parameters +- `sh_tsc_is_tsc_constant()`: return `SH_TRUE` if the TSC is constant, according to CPU ID +- `sh_tsc_get_cpu_freq_cpuid()`: return in a variable given as a pointer the value of the CPU frequency given by CPU ID id available. Return a `SH_STATUS` +- `sh_tsc_devs_query()`: TSC DevS entry point, should only be called by `sh_devs_query` diff --git a/docs/shelter/devs/abstracted/ps2.md b/docs/shelter/devs/abstracted/ps2.md new file mode 100644 index 0000000..ed97b4a --- /dev/null +++ b/docs/shelter/devs/abstracted/ps2.md @@ -0,0 +1,36 @@ +# PS2 keyboard + +The PS2 keyboard driver is defined in `shelter/lib/include/devs/input/ps2.h` and implemented in `shelter/lib/src/devs/input/ps2.c`. This documentation only describes the public API, the one that is safe to access from external subsystems. + +## Driver initialization + +The PS2 is initialized using `sh_ps2_driver_init()`. The pre-requirement for this function include the keyboard input subsystem being initialized. Here is the exact procedure: +1) Disable interrupts for safety +2) Flush output buffer +3) Debug log status and config byte initial value +4) Disable keyboard and mouse PS2 ports +5) Reflush output buffer for safety +6) Disable both ports IRQs +7) Perform the PS2 controller self test +8) Enable port 1 +9) Enable scancodes translation +10) Initialize driver internal state +11) Enable IRQ for port 1 +12) Register interrupt handler for legacy IRQ1 +13) Enable interrupts +14) Disable scanning +15) Reset leds state +16) Identify keyboard +17) Register PS2 keyboard to the keyboard input subsystem +18) Enable scanning + +For the moments, commands responses handling and scancodes parsing is working but there are a few limitations: +- since we only parsed a few ACPI tables, we are unable to detect with certainty the presence of a PS2 controller. So the system consider that the PS2 controller is available and working and the keyboard device registered to the keyboard input subsystem will always be marked as present +- any error in the driver initialization will be interpreted as a failure of the boot process +- for the moment, we are unable to defer the leds state update when a scancode change the NumLock/CapsLock state, so these leds won't update + +## API + +A few additionnal functions are provided: +- `sh_ps2_disable_scanning()`: disable PS2 keyboard scanning +- `sh_ps2_enable_scanning()`: enable PS2 keyboard scanning diff --git a/docs/shelter/devs/acpi.md b/docs/shelter/devs/acpi.md new file mode 100644 index 0000000..7a95d41 --- /dev/null +++ b/docs/shelter/devs/acpi.md @@ -0,0 +1,43 @@ +# ACPI Parsing + +Shelter only support the ACPI v2 and newer ACPI specifications. That mean the XSDT pointer must exists. + +## Root structures parsing + +The root structures parsing is defined in `shelter/lib/include/devs/acpi.h` and implemented in `shelter/lib/src/devs/acpi.c`. + +The `sh_acpi_parse_rsdp()` function takes the RSDP and completes a `sh_apci_ACPI_POINTERS_ROOT` structure that look like this: +``` C +typedef struct { + sh_uint64 rsdt; + sh_uint64 xsdt; +} sh_apci_ACPI_POINTERS_ROOT; +``` + +Then, the `sh_acpi_parse_xsdt()` function takes the XSDT pointer and parses the XSDT header. It ensures that the structure isn't corrupted, and map all the entries. At the end, it completes this structure: +``` C +typedef struct { + sh_uint64 *entries; + sh_uint64 entry_count; +} sh_acpi_ACPI_XSDT_BODY; +``` + +Finally, the `sh_acpi_parse_tables()` takes the `sh_acpi_ACPI_XSDT_BODY` structure and parses all the entries. It ensures that at least the first pages of each table is mapped. All the tables pointers are sorted in a structure that look like this: +``` C +typedef struct { + sh_uint64 madt_physical_address; +} sh_acpi_ACPI_TABLES; +``` + +## Tables parsing + +The parsing of ACPI tables is delegated to several functions, one for each tables. Here are the tables that are currently supported: +- MADT + +All parsing functions are defined in the files inside `shelter/lib/include/devs/acpi_tables` and in the files inside `shelter/lib/src/devs/acpi_tables`. + +### MADT parsing + +The MADT is parsed using the `sh_acpi_madt_parse(sh_uint64 madt_ptr)`, defined in `shelter/lib/include/devs/acpi_tables/madt.h` and implemented in `shelter/lib/src/devs/acpi_tables/madt.c`. + +This function logs all the entries and register all LAPIC devices, IOAPIC devices and ISOs. diff --git a/docs/shelter/devs/devs.md b/docs/shelter/devs/devs.md new file mode 100644 index 0000000..4198286 --- /dev/null +++ b/docs/shelter/devs/devs.md @@ -0,0 +1,142 @@ +# DevS querying + +## Introduction + +The Device System provides a central way to query various kernel subsystems. It is defined in `shelter/lib/include/devs/devs.h` and implemented in `shelter/lib/src/devs/devs.c`. + +## Entry point + +All DevS related API call goes through a standard entry point: +``` C +sh_devs_query(char *path,sh_devs_RESULT *result) +``` + +The result is stored inside `result`, which is a structure like this: +``` C +typedef struct { + enum sh_devs_RESULT_TYPE type; + sh_uint64 value; +} sh_devs_RESULT; +``` + +There are severals returned types: +- `SH_DEVS_VALUE`: a 64 bits value +- `SH_DEVS_BOOL`: a boolean stored inside `value` by casting the `sh_bool` to `sh_uint64` +- `SH_DEVS_LAPIC`: `value` should be casted to `sh_lapic_DEVICE*`, which points directly to a LAPIC device structure +- `SH_DEVS_IOAPIC`: `value` should be casted to `sh_ioapic_DEVICE*`, which points directly to a IOAPIC device structure + +Each endpoint has a specific syntax, but here are the common syntax elements: +- each path starts with the `$` sign +- each subsystem has its own prefix + +Unless you are querying for a pointer (in this case, you can modify the value inside the pointed structure), you can't write anything in the DevS endpoints. + +## Endpoint categories + +All the kernel subsystems that expose datas through the DevS provide a function to parse the rest of the path without the subsystem prefix once `sh_devs_query()` dispatched the query. + +These functions aren't documented in the documentation of these subsystems and shouldn't be called directly. + +### LAPIC endpoints + +Function: +``` C +sh_lapic_devs_query(char *sub_path,sh_devs_RESULT *result) +``` + +Prefix: `$apic/lapic` + +Endpoints: + +Path with syntax | Returned type | Description +-----------------|---------------|------------ +`$apic/lapic/by-apic-id/` | `SH_DEVS_LAPIC` | Return the struct of the LAPIC device correspoding to the provided LAPIC id. **Can return `SH_NULLPTR` with a success due to sparses id** +`$apic/lapic/by-acpi-id/` | `SH_DEVS_LAPIC` | Return the struct of the LAPIC device correspoding to the provided ACPI processor id. **Can return `SH_NULLPTR` with a success due to sparses id** +`$apic/lapic/count` | `SH_DEVS_VALUE` | Return the number of LAPIC devices registered +`$apic/lapic/timer-frequency` | `SH_DEVS_VALUE` | Return the estimated frequency of the LAPIC timer +`$apic/lapic/max-apic-id` | `SH_DEVS_VALUE` | Return the biggest LAPIC id among all registered LAPIC devices +`$apic/lapic/max-acpi-id` | `SH_DEVS_VALUE` | Return the biggest ACPI processor id among all registered LAPIC devices +`$apic/lapic/base-address` | `SH_DEVS_VALUE` | Return the physical address of the memory mapped pages for LAPICs +`$apic/lapic/this-cpu-lapic` | `SH_DEVS_LAPIC` | Return the struct of the LAPIC device corresponding to this CPU + +### IOAPIC endpoints + +Function: +``` C +sh_ioapic_devs_query(char *sub_path,sh_devs_RESULT *result) +``` + +Prefix: `$apic/ioapic` + +Endpoints: + +Path with syntax | Returned type | Description +-----------------|---------------|------------ +`$apic/ioapic/by-ioapic-id/` | `SH_DEVS_ioAPIC` | Return the struct of the IOAPIC device correspoding to the provided IOAPIC id. **Can return `SH_NULLPTR` with a success due to sparses id** +`$apic/lapic/by-gsi/` | `SH_DEVS_IOAPIC` | Return the struct of the IOAPIC device that manages the corresponding GSI. **Can return `SH_NULLPTR` with a success due to sparses GSI** +`$apic/lapic/count` | `SH_DEVS_VALUE` | Return the number of IOAPIC devices registered +`$apic/lapic/max-ioapic-id` | `SH_DEVS_VALUE` | Return the biggest IOAPIC id among all registered IOAPIC devices + +### TSC endpoints + +Function: +``` C +sh_tsc_devs_query(char *sub_path,sh_devs_RESULT *result) +``` + +Prefix: `$tsc` + +Endpoints: + +Path with syntax | Returned type | Description +-----------------|---------------|------------ +`$tsc/kernel-init-tsc` | `SH_DEVS_VALUE` | Return the TSC value saved at the start of the kernel C entry point, before AP bootstrap +`$tsc/cpu-freq` | `SH_DEVS_VALUE` | Return the CPU frequency, either estimated or provided by CPU ID +`$tsc/is-cpu-freq-provided` | `SH_DEVS_BOOL` | Return `SH_TRUE` if CPU frequency is provided by CPU ID, `SH_FALSE` if CPU frequency is estimated + +### Kernel config endpoints + +Function: +``` C +sh_conf_devs_query(char *sub_path,sh_devs_RESULT *result) +``` + +Prefix: `$kernel/conf` + +Endpoints: + +Path with syntax | Returned type | Description +-----------------|---------------|------------ +`$kernel/conf/log-level` | `SH_DEVS_VALUE` | Return the log level of the kernel +`$kernel/conf/test-benchmark` | `SH_DEVS_BOOL` | Return the test-benchmark state, `SH_TRUE` if enabled +`$kernel/conf/bench-iterations` | `SH_DEVS_VALUE` | Return the amount of iterations used for benchmarking +`$kernel/conf/disable-serial-port` | `SH_DEVS_BOOL` | Return `SH_TRUE` if serial port is disabled, `SH_FALSE` otherwise +`$kernel/conf/kbd-events-queue-capacity` | `SH_DEVS_VALUE` | Return the amount of events a keyboard events queue can store + +### Memory subsystem endpoints + +Function: +``` C +sh_memory_devs_query(char *sub_path,sh_devs_RESULT *result) +``` + +Prefix: `$memory` + +Endpoints: + +Path with syntax | Returned type | Description +-----------------|---------------|------------ +`$memory/free-pages` | `SH_DEVS_VALUE` | Return the amount of free pages in the Pez physical plane +`$memory/used-pages` | `SH_DEVS_VALUE` | Return the amount of allocated pages in the Pez physical plane +`$memory/total-pages` | `SH_DEVS_VALUE` | Return the amount of physical pages detected when parsing the memory map +`$memory/installed-pages` | `SH_DEVS_VALUE` | Return the amount of pages detected usable when parsing the memory map. Can be slightly smaller than total pages + +### SMP endpoints + +Function: integrated to `sh_devs_query()` + +Prefix: `$smp` + +Path with syntax | Returned type | Description +-----------------|---------------|------------ +`$smp/cpu-count` | `SH_DEVS_VALUE` | Return the number of processors diff --git a/docs/shelter/devs/drivers.md b/docs/shelter/devs/drivers.md new file mode 100644 index 0000000..f568f54 --- /dev/null +++ b/docs/shelter/devs/drivers.md @@ -0,0 +1,18 @@ +# Device drivers + +## Overview + +The current device drivers are scattered through the `shelter/lib/include/devs` folder. There is two kinds of devices drivers: +- integrated: these one are used as a core part of the kernel, and aren't exposed through subsystem abstraction +- abstracted: these one are abstracted using a specific subsystem depending on the device type that provides a standard API both for drivers and consumers + +## Integrated drivers + +For the moment, integrated drivers are implemented for the following devices: +- [LAPIC devices](integrated/lapic.md) +- [IOAPIC devices](integrated/ioapic.md) + +## Abstracted drivers + +For the moment, abstracted drivers are implemented for the following devices: +- [PS2 keyboard](abstracted/ps2.md) diff --git a/docs/shelter/devs/index.md b/docs/shelter/devs/index.md new file mode 100644 index 0000000..e0780d0 --- /dev/null +++ b/docs/shelter/devs/index.md @@ -0,0 +1,13 @@ +# Device System + +## Introduction + +The Device System (also called DevS) is the entire subsystem managing everything related to ACPI parsing and devices abstractions. + +## Overview + +The DevS is splitted in several subparts: +- [ACPI parsing](acpi.md) +- [Device drivers](drivers.md) +- [Keyboard input subsystem](kbdinput.md) +- [DevS querying](devs.md) diff --git a/docs/shelter/devs/integrated/ioapic.md b/docs/shelter/devs/integrated/ioapic.md new file mode 100644 index 0000000..35f916c --- /dev/null +++ b/docs/shelter/devs/integrated/ioapic.md @@ -0,0 +1,35 @@ +# IOAPIC devices + +This driver is defined inside `shelter/lib/include/devs/apic/ioapic.h` and implemented inside `shelter/lib/src/devs/apic/ioapic.c`. + +## Driver initialization + +During the MADT parsing, all IOAPIC entries are counted. Then, a call to `sh_ioapic_init_devs(sh_uint8 max_lapic_id)` is made to initialize the driver internal state. This call allocates an array indexed by IOAPIC id. + +## Device initialization + +After that, each time a IOAPIC entry is parsed, a call to `sh_ioapic_init(sh_uint32 base,sh_uint8 ioapic_id,sh_uint32 gsi_base,sh_ioapic_DEVICE *ioapic)` is made. This does three things: +1) Identity map the memory space for the LAPIC +2) Fill the structure for the LAPIC device +3) Initialize the device without modifying the IOREDTBL for the moment + +Then, a call to `sh_ioapic_bind(sh_ioapic_DEVICE *ioapic_dev)` is made, registering the LAPIC structure in the array. + +## Basic IOAPIC management + +For basic IOAPIC management, the following function are provided: +- `sh_ioapic_get_dev_ioapic_id(sh_uint64 ioapic_id)`: return a `sh_ioapic_DEVICE*` pointing to the IOAPIC structure corresponding to the provided IOAPIC id +- `sh_ioapic_get_dev_by_gsi(sh_uint32 gsi)`: return a `sh_ioapic_DEVICE*` pointing to the IOAPIC structure of the IOAPIC that manages the provided GSI +- `sh_ioapic_read_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry)`: read a IOREDTBL entry and put its value into `entry`. If the GSI isn't managed by the provided device, raise an error +- `sh_ioapic_write_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry)`: write and IOREDTBL entry corresponding to the provided GSI. If the GSI isn't managed by the provided device, raise an error + +IOREDTBL read and write are thread-safe operations. + +## Higher level operations + +The following higher level operations are provided: +- `sh_ioapic_mask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi)`: mask the provided GSI. If the GSI isn't managed by the provided device, raise an error +- `sh_ioapic_unmask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi)`: unmask the provided GSI. If the GSI isn't managed by the provided device, raise an error +- `sh_ioapic_mask_all()`: mask all the GSI for all registered IOAPIC. + +If you are looking for an even more abstracted API, please check the GSI subsystem. diff --git a/docs/shelter/devs/integrated/lapic.md b/docs/shelter/devs/integrated/lapic.md new file mode 100644 index 0000000..a817154 --- /dev/null +++ b/docs/shelter/devs/integrated/lapic.md @@ -0,0 +1,81 @@ +# LAPIC devices + +This driver is defined inside `shelter/lib/include/devs/apic/lapic.h` and implemented inside `shelter/lib/src/devs/apic/lapic.c`. + +## Driver initialization + +During the MADT parsing, all LAPIC entries are counted. Then, a call to `sh_lapic_init_devs(sh_uint16 max_lapic_id,sh_uint16 max_acpi_processor_id)` is made to initialize the driver internal state. This call allocates two arrays: one indexed by LAPIC id and one indexed by ACPI processors id. + +## Device initialization + +After that, each time a LAPIC entry is parsed, a call to `sh_lapic_init(sh_uint64 lapic_phys,sh_uint8 spurious_vector,sh_uint8 apic_id,sh_uint8 apic_processor_id,sh_uint32 flags,sh_lapic_DEVICE *lapic)` is made. This does two things: +1) Identity map the memory space for the LAPIC +2) Fill the structure for the LAPIC device + +Then, a call to `sh_lapic_bind(sh_lapic_DEVICE *lapic_dev)` is made, registering the LAPIC structure in both arrays. + +Finally, when the MADT parsing is over, a call to `sh_lapic_init_dev(sh_uint8 spurious_vector,sh_lapic_DEVICE *lapic)` initialize the LAPIC by setuping a few of its registers. + +## Basic LAPIC management + +For basic LAPIC management, the following functions are provided: +- `sh_lapic_eoi(sh_lapic_DEVICE *lapic)`: send a End Of Interrupt (EOI) to the LAPIC +- `sh_lapic_get_dev_apic_id(sh_uint64 apic_id)`: return a `sh_lapic_DEVICE*` pointing to the LAPIC structure corresponding to the provided APIC id +- `sh_lapic_get_dev_acpi_cpu_id(sh_uint64 acpi_processor_id)`: return a `sh_lapic_DEVICE*` pointing to the LAPIC structure corresponding to the provided ACPI processor id +- `sh_lapic_get_by_apic_id_array()`: return a `sh_lapic_DEVICE**` of the LAPIC devices pointers array, indexed by LAPIC id +- `sh_lapic_get_max_apic_id()`: return the max LAPIC id +- `sh_lapic_get_max_acpi_processor_id()`: return the max ACPI processor id +- `sh_lapic_get_lapic_count()`: return the number of registered LAPICs +- `sh_lapic_get_current_core()`: return the LAPIC id of the current core, return -1 if error happened + +## LAPIC timer + +To launch a one shot timer without knowing the frequency, the `sh_lapic_timer_one_shot(sh_lapic_DEVICE *lapic_dev,sh_uint32 initial_value)` can be used. + +But the LAPIC driver provides a way to calibrate the LAPIC in order to obtain its frequency. For this, we use the following process: +1) Launch a timer with max value +2) Read the start TSC and current LAPIC value, iterate for 10 millions times, read the end TSC and current LAPIC value. +3) Compute `tsc_delta` and `lapic_delta` +4) Using the following formula, estimate the LAPIC frequency: `lapic_freq = (lapic_delta * cpu_freq) / tsc_delta` + +This calibration process is implemented in `sh_lapic_calibrate(sh_lapic_DEVICE *lapic_dev,sh_uint64 cpu_freq)`. But the TSC frequency estimation must have been achevied before that. + +When the LAPIC frequency is obtained, two new functions are unlocked: +- `sh_lapic_get_frequency()`: return the estimated LAPIC frequency +- `sh_lapic_timer_one_shot_us(sh_lapic_DEVICE *lapic_dev,sh_uint64 microseconds_count)`: launch a one shot timer by taking a value in microsecond. Compute the initial value using the estimated frequency before hand. + +## IPI management + +The LAPIC driver provides a helper to know if the LAPIC IPI feature is busy: `sh_lapic_ipi_is_busy(sh_lapic_DEVICE *lapic_dev)`. + +### Sending a fixed IPI + +The primitive to send a fixed IPI is: +``` C +sh_lapic_send_fixed_ipi(sh_lapic_DEVICE *lapic_dev,sh_uint8 vector,sh_uint32 destination_mode,sh_int16 target_lapic_id); +``` + +`lapic_dev` must be the struct of the LAPIC of the current CPU. + +`destination_mode` can either be `SH_LAPIC_IPI_DESTINATION_SPECIFIC`, `SH_LAPIC_IPI_DESTINATION_SELF`, `SH_LAPIC_IPI_DESTINATION_ALL` or `SH_LAPIC_IPI_DESTINATION_ALL_EXCLUDING_SELF`. + +If `destination_mode` isn't `SH_LAPIC_IPI_DESTINATION_SPECIFIC`, `target_lapic_id` must be `SH_LAPIC_IPI_NO_DESTINATION`. + +### Sending any others IPI + +The primitive to send any other IPI than a fixed IPI is: +``` C +sh_lapic_send_ipi(sh_lapic_DEVICE *lapic_dev,sh_uint32 ipi_type,sh_uint32 destination_mode,sh_int16 target_lapic_id,sh_page_PHYSICAL_ADDRESS start_address); +``` + +`lapic_dev` must be the struct of the LAPIC of the current CPU. + +`ipi_type` can either be `SH_LAPIC_IPI_TYPE_INIT`, `SH_LAPIC_IPI_TYPE_STARTUP` or `SH_LAPIC_IPI_TYPE_NMI`. + +If `ipi_type` is `SH_LAPIC_IPI_TYPE_STARTUP`, `start_address` must contain the starting address. Address constraint (compatible with 16 bits mode) are checked. + +If `ipi_type` isn't `SH_LAPIC_IPI_TYPE_STARTUP`, `start_address` must be 0. + +`destination_mode` can either be `SH_LAPIC_IPI_DESTINATION_SPECIFIC`, `SH_LAPIC_IPI_DESTINATION_SELF`, `SH_LAPIC_IPI_DESTINATION_ALL` or `SH_LAPIC_IPI_DESTINATION_ALL_EXCLUDING_SELF`. + +If `destination_mode` isn't `SH_LAPIC_IPI_DESTINATION_SPECIFIC`, `target_lapic_id` must be `SH_LAPIC_IPI_NO_DESTINATION`. diff --git a/docs/shelter/devs/kbdinput.md b/docs/shelter/devs/kbdinput.md new file mode 100644 index 0000000..8e85eb6 --- /dev/null +++ b/docs/shelter/devs/kbdinput.md @@ -0,0 +1,134 @@ +# Keyboard input subsystem + +## Introduction + +The keyboard input subsystem is responsible for abstracting keyboard devices and keyboards events. It's defined in `shelter/lib/include/devs/input/kbd.h` and implemented in `shelter/lib/src/devs/input/kbd.c`. It's still in the early stage and isn't finished for the moment. + +## Overview + +The keyboard input subsystem is based on two key concepts: +- keyboard devices: this is the standard abstraction for any keyboard-like devices +- keyboard events: provides a standard way to interpret any events from any keyboard devices + +The keyboard input subsystem is initialized using `sh_kbd_init_devs()`. + +### Keyboard devices + +### Driver side + +The keyboard device structure look like this: +``` C +typedef struct { + sh_uint8 kbd_id; + sh_queue_KBD_EVENT *events_queue; + sh_bool present; + sh_bool ver_maj; + sh_bool ver_num; + sh_bool shift; + sh_bool alt; + sh_bool ctrl; + sh_bool win; + sh_SPIN_LOCK spinlock; +} sh_kbd_DEVICE; +``` + +Each keyboard device is identified with a keyboard id. When a keyboard is unregistered, the keyboard id can be recycled for a new keyboard device. There is a maximum of 256 keyboards id, and so 256 maximum registered keyboard devices at the same time. + +The keyboard id 0 is reserved for the PS2 keyboard. It's always valid, even if there is no PS2 controller. + +The `present` boolean defines if the keyboard is present. If `present` is `SH_FALSE`, no actions except unregistering the keyboard is allowed on the keyboard device. + +The `present` boolean for the keyboard od keyboard id 0 indicates if the PS2 controller is available. + +There is two primitives to register keyboards devices: +- `sh_kbd_register_ps2(sh_bool is_present,sh_kbd_DRIVER_HANDLE **handle)`: register the PS2 keyboard, reserved for the PS2 driver +- `sh_kbd_register(sh_bool is_present,sh_kbd_DRIVER_HANDLE **handle)`: register a new keyboard device + +Upon registration, a `sh_kbd_DRIVER_HANDLE` struct is completed. It became non valid when the keyboard is unregistered. It is reserved for driver usage only. + +Two primitives accessible to drivers require this driver handle: +- `sh_kbd_set_flag(sh_kbd_DRIVER_HANDLE *handle,sh_uint8 flag,sh_bool value)`: set a flag about the keyboard corresponding to the provided driver handle +- `sh_kbd_push_events(sh_kbd_DRIVER_HANDLE *handle,sh_kbd_EVENT *event)`: push an event in the events queue of the keyboard device corresponding to the provided driver handle + +There is, for the moment, no primitive to unregister a keyboard. + +### Consumer side + +Four functions are available for consumers: +- `sh_kbd_enumerate_devices(sh_kbd_ENUMERATION *enumeration)`: complete a `sh_kbd_ENUMERATION` structure, each bit set to 1 correspond to a valid keyboard id +- `sh_kbd_get_handle(sh_uint8 kbd_id,sh_kbd_CONSUMER_HANDLE **handle)`: return a valid consumer handle for the provided keyboard id. It uses `sh_malloc` +- `sh_kbd_destroy_handle(sh_kbd_CONSUMER_HANDLE **handle)`: free the provided consumer handle +- `sh_kbd_read_flag(sh_kbd_DRIVER_HANDLE *d_handle,sh_kbd_CONSUMER_HANDLE *c_handle,sh_uint8 flag,sh_bool *value)`: read a flag about the keyboard corresponding to the provided handle. Accepts either a driver or consumer handle, but fails if both handle are provided. + +The possible flags to read/write are: `SH_KBD_FLAG_PRESENT`, `SH_KBD_FLAG_VER_MAJ`, `SH_KBD_FLAG_VER_NUM`, `SH_KBD_FLAG_SHIFT`, `SH_KBD_FLAG_ALT`, `SH_KBD_FLAG_CTRL`, `SH_KBD_FLAG_WIN`. + +There is, for the moment, no way to read keyboards events. + +## Keyboard events + +A keyboard event is represented by this structure: +``` C +typedef struct { + sh_uint16 scancode; + sh_bool pressed; + sh_uint8 context_shift_win; + sh_uint8 context_alt; + sh_uint8 context_ctrl; + sh_uint8 context_lock_status; + sh_uint8 event_type; + sh_uint64 timestamp; +} sh_kbd_EVENT; +``` + +All non-pause events contain a snapshot of keyboard context state at emission time, before the state of corresponding flag in the keyboard device changes. These fields remain valid even for `SH_EVENT_TYPE_KBD_CONTEXT`: +- `context_shift_win`: + - Bit 0: shift active, checked with macro `SH_KBD_EVENT_SHIFT_ACTIVE` + - Bit 1: win active, checked with macro `SH_KBD_EVENT_WIN_ACTIVE` +- `context_alt`: + - Bit 0: right alt active, checked with macro `SH_KBD_EVENT_RIGHT_ACTIVE` + - Bit 1: left alt active, checked with macro `SH_KBD_EVENT_LEFT_ACTIVE` +- `context_ctrl`: + - Bit 0: right control active, checked with macro `SH_KBD_EVENT_RIGHT_ACTIVE` + - Bit 1: left control active, checked with macro `SH_KBD_EVENT_LEFT_ACTIVE` +- `context_lock_status`: + - Bit 0: numlock active, checked with `SH_KBD_EVENT_NUMLOCK_ACTIVE` + - Bit 0: capslock active, checked with `SH_KBD_EVENT_CAPSLOCK_ACTIVE` + +There is a precise way of interpreting what this structure mean. It start by checking the value of `event_type`. + +### `SH_EVENT_TYPE_KBD_PAUSE` + +The event is a press of the pause key. The `scancode` and `pressed` fields should be ignored. + +### `SH_EVENT_TYPE_KBD_CONTEXT` + +This event is a press of a modifier key. It allows to abstract modifiers keys events accross all types of keyboards. + +The scancode must be one of the following: +- `SH_KBD_CONTEXT_LSHIFT` +- `SH_KBD_CONTEXT_RSHIFT` +- `SH_KBD_CONTEXT_LCTRL` +- `SH_KBD_CONTEXT_RCTRL` +- `SH_KBD_CONTEXT_LALT` +- `SH_KBD_CONTEXT_RALT` +- `SH_KBD_CONTEXT_WIN` +- `SH_KBD_CONTEXT_NUMLOCK` +- `SH_KBD_CONTEXT_CAPSLOCK` + +You need to check the `pressed` boolean to know if the key was pressed or released. + +### `SH_EVENT_TYPE_PS2_NORMAL` + +This event type represents a standard PS2 Set1 scancode. The scancode is put in the low 8 bits of the `scancode` fields. The high 8 bits are set to 0. + +You need to check the `pressed` boolean to know if the key was pressed or released. + +### `SH_EVENT_TYPE_PS2_E0` + +This event type represents an extended PS2 Set1 scancode prefixed by `0xE0`. The scancode is put in the low 8 bits of the `scancode` fields. The high 8 bits are set to `0xE0`. + +You need to check the `pressed` boolean to know if the key was pressed or released. + +### Notes + +For `SH_EVENT_TYPE_PS2_NORMAL` and `SH_EVENT_TYPE_PS2_E0` events type, the scancode, when `pressed` is `SH_FALSE`, keeps its bit 8 to 1. diff --git a/docs/shelter/index.md b/docs/shelter/index.md index 1edbbee..eff1d0d 100644 --- a/docs/shelter/index.md +++ b/docs/shelter/index.md @@ -10,12 +10,14 @@ Shelter stricly follow these principles: - absolutely no external code inside it. All the code that run in ring 0 should be sovereign - absolutely no UNIX dependency on design philosophy. Shelter follow his own rules for kernel design (but doesn't forbid itself to reuse somes UNIX concepts), even if it mean spending years designing, refining and standardizing them - a very strict boot process that ensure that everything goes well during the system boot -- fully made in C +- fully made in C (and a bit of ASM only where necessary) - focuses on auditability, self-testing and benchmarking, and determinism - use his own algorithms for various very important components of every kernel (mainly memory management, scheduling, etc), except on cryptographic algorithms, which follow a very strict integration processus The Shelter kernel is currently in very early developpement stage and isn't suitable at all for every-day usage. +x2APIC isn't supported yet, so all of the code related to CPU manipulation is optimized for maximum 256 CPUs. + ## Summary - Key principles to know in order to boot Shelter @@ -32,4 +34,6 @@ The Shelter kernel is currently in very early developpement stage and isn't suit - [Kernel-specific APIs](kernel/kernel.md) - [Memory subsystem](memory/index.md) - [Test-and-benchmark framework](tab.md) + - [Devices System](devs/index.md) + - [IRQ subsystem](irq/index.md) - [Benchmark results](bench.md) diff --git a/docs/shelter/irq/gdt.md b/docs/shelter/irq/gdt.md new file mode 100644 index 0000000..975f005 --- /dev/null +++ b/docs/shelter/irq/gdt.md @@ -0,0 +1,98 @@ +# GDT + +The GDT management is defined in `shelter/lib/include/irq/gdt.h` and implemented in `shelter/lib/include/irq/gdt.c`. + +## 64 bits GDT + +The 64 bits GDT can contains two types of entries: +- `sh_gdt_GDT_ENTRY_64`: standard GDT entry +- `sh_gdt_GDT_ENTRY_128`: special 128 bits GDT entry for TSS + +The standard 64 bits GDT used during the boot process is contained in this structure: +``` C +#pragma pack(1) +typedef struct { + sh_gdt_GDT_ENTRY_64 null; + sh_gdt_GDT_ENTRY_64 kernel_code; + sh_gdt_GDT_ENTRY_64 kernel_data; + sh_gdt_GDT_ENTRY_64 user_code; + sh_gdt_GDT_ENTRY_64 user_data; + sh_gdt_GDT_ENTRY_128 tss; +} sh_gdt_GDT; +#pragma pack() +``` + +We also use this struct for generating the 10 bytes to use with `lgdt`: +``` C +#pragma pack(1) +typedef struct { + sh_uint16 limit; + sh_uint64 base; +} sh_gdt_GDTR; +#pragma pack() +``` + +Regarding the API, we provide the following functions: +- `sh_gdt_fill_access_byte(sh_bool present,sh_uint8 dpl,sh_bool descriptor_type,sh_uint8 segment_type)`: generate access byte +- `sh_gdt_fill_flags_byte(sh_bool g,sh_bool db,sh_bool l,sh_bool avl)`: generate flags byte +- `sh_gdt_fill_gdt_entry_64(sh_uint32 limit,sh_uint32 base,sh_uint8 access,sh_uint8 flags)`: fill a 64 bits GDT entry, expect flags as `sh_gdt_fill_flags_byte` would return it +- `sh_gdt_fill_gdt_entry_128(sh_uint32 limit,sh_uint64 base,sh_uint8 access,sh_uint8 flags)`: fill a 128 bits GDT entry, expect flags as `sh_gdt_fill_flags_byte` would return it +- `sh_gdt_fill_gdt(sh_tss_TSS *tss,sh_gdt_GDT *gdt)`: fill the standard 64 bits GDT with the provided TSS +- `sh_gdt_load_gdtr(sh_gdt_GDT *gdt)`: load the standard 64 bits GDT using `lgdt` +- `sh_gdt_reload_registers()`: an ASM stub to reload segment registers + +All these functions are intended to be used with the standard 64 bits GDT defined with `sh_gdt_GDT`, which should only be used on the bootstrap CPU + +## APs GDT + +The APs use a special GDT containing sufficient spaces for the TSS entries of all APs. + +For that we use a special shared 64 bits GDT between all APs, defined in this struct: +``` C +#pragma pack(1) +typedef struct { + sh_gdt_GDT_ENTRY_64 null; + sh_gdt_GDT_ENTRY_64 kernel_code; + sh_gdt_GDT_ENTRY_64 kernel_data; + sh_gdt_GDT_ENTRY_64 user_code; + sh_gdt_GDT_ENTRY_64 user_data; + sh_gdt_GDT_ENTRY_128 tss[256]; +} sh_gdt_GDT_AP; +#pragma pack() +``` + +The APs GDT is generated using the function `sh_gdt_fill_gdt_ap(sh_tss_TSS *tss,sh_uint64 tss_count,sh_gdt_GDT_AP *gdt)`. This allows to fill a GDT with up to 256 TSS entries. The GDTR for this shared GDT is generated using `sh_gdt_make_gdtr_ap(sh_gdt_GDT_AP *gdt)`. + +## 32 bits GDT + +In order for the APs to exit 16 bits mode, they need a 32 bits GDT. Here is the structure for a 32 bits GDT entry: +``` C +#pragma pack(1) +typedef struct { + sh_uint16 limit_low; + sh_uint16 base_low; + sh_uint8 base_middle; + sh_uint8 access; + sh_uint8 granularity; + sh_uint8 base_high; +} sh_gdt_GDT_ENTRY_32; +#pragma pack() +``` + +The 32 bits GDT used to exit 16 bits mode is structured like this: +``` C +#pragma pack(1) +typedef struct { + sh_gdt_GDT_ENTRY_32 null; + sh_gdt_GDT_ENTRY_32 code_64; + sh_gdt_GDT_ENTRY_32 code; + sh_gdt_GDT_ENTRY_32 data; +} sh_gdt_GDT_32; +#pragma pack() +``` + +The 32 bits GDT implementation provides the following functions: +- `sh_gdt_fill_access_byte_32(sh_bool present,sh_uint8 dpl,sh_bool descriptor_type,sh_uint8 segment_type)`: generate access byte +- `sh_gdt_fill_granularity_byte_32(sh_bool granularity,sh_bool db,sh_bool l,sh_bool avl)`: generate granularity byte +- `sh_gdt_fill_gdt_entry_32(sh_uint32 limit,sh_uint32 base,sh_uint8 access,sh_uint8 granularity)`: fill a GDT entry for a 32 bits GDT, expect flags as `sh_gdt_fill_flags_byte_32` would return it +- `sh_gdt_fill_gdt_32(sh_gdt_GDT_32 *gdt_32)`: fill the 32 bits GDT structure diff --git a/docs/shelter/irq/gsi.md b/docs/shelter/irq/gsi.md new file mode 100644 index 0000000..ff88fa4 --- /dev/null +++ b/docs/shelter/irq/gsi.md @@ -0,0 +1,68 @@ +# GSI subsystem + +## Introduction + +This subsystem is responsible for registering all the interrupts sources overrides (ISO) and providing an abstraction to manipulate all the GSI lines and legacy IRQs. + +## ISOs registering + +The subsystem can be initialized using `sh_gsi_iso_array_init()`. This allocate an array of 256 `sh_gsi_ISO` in which all the ISOs will be stored. + +The ISO struct is the following: +``` C +typedef struct { + sh_uint32 gsi; + sh_bool valid; + sh_uint8 source_irq; + enum sh_gsi_POLARITY polarity; + enum sh_gsi_TRIGGER_MODE trigger_mode; + sh_uint8 bus; +} sh_gsi_ISO; +``` + +Any `sh_gsi_ISO` without the valid boolean to `SH_TRUE` should be considered as not occupied in the array. + +The `sh_gsi_POLARITY` enum can take the following values: +``` C +enum sh_gsi_POLARITY { + SH_GSI_POLARITY_NOT_SET=0, + SH_GSI_POLARITY_BUS_DEFAULT, + SH_GSI_POLARITY_ACTIVE_HIGH, + SH_GSI_POLARITY_ACTIVE_LOW +}; +``` + +The `sh_gsi_TRIGGER_MODE` enum can take the following values: +``` C +enum sh_gsi_TRIGGER_MODE { + SH_GSI_TRIGGER_MODE_NOT_SET=0, + SH_GSI_TRIGGER_MODE_BUS_DEFAULT, + SH_GSI_TRIGGER_MODE_EDGE, + SH_GSI_TRIGGER_MODE_LEVEL +}; +``` + +Bus defaults are resolved when configuring the IOREDTBL of each IOAPIC. + +During the MADT table parsing, ISOs are registered using the `sh_gsi_iso_register(sh_uint8 bus,sh_uint8 source,sh_uint32 gsi,sh_uint16 flags)` function, which expects the arguments as they are parsed in the MADT table. + +Two functions can be used to search for ISOs: +- `sh_gsi_get_iso_by_irq(sh_uint8 irq)`: return a `*sh_gsi_ISO` with the provided legacy IRQ number. Return `SH_NULLPTR` if not found or error +- `sh_gsi_get_iso_by_gsi(sh_uint32 gsi)`: return a `*sh_gsi_ISO` with the provided GSI number. Return `SH_NULLPTR` if not found or error + +## IOAPIC abstraction + +The GSI subsystem provides an abstraction to manipulate IOREDTBL entries based on the GSI or legacy IRQ number without interacting directly with the IOAPIC subsystem. The following functions are provided: +- `sh_gsi_get(sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry)`: return the IOREDTBL entry corresponding to the provided GSI +- `sh_gsi_set(sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry)`: set the IOREDTBL entry corresponding to the provided GSI with the provided entry. Automatically mask the IOREDTBL entry before writing the entry +- `sh_gsi_irq_set(sh_uint8 irq,sh_ioapic_IOREDTBL_ENTRY *entry)`: do the same as `sh_gsi_set()` but retrieves the original GSI before hand, taking into account registered ISOs +- `sh_gsi_mask(sh_uint32 gsi)`: mask the IOREDTBL entry corresponding to the provided GSI +- `sh_gsi_unmask(sh_uint32 gsi)`: unmask the IOREDTBL entry corresponding to the provided GSI +- `sh_gsi_irq_mask(sh_uint8 irq)`: do the same as `sh_gsi_mask()` but retrieves the original GSI before hand, taking into account registered ISOs +- `sh_gsi_irq_unmask(sh_uint8 irq)`: do the same as `sh_gsi_unmask()` but retrieves the original GSI before hand, taking into account registered ISOs + +## Legacy IRQs switch + +What we call the legacy IRQs switch is the mapping of all the legacy IRQs to interrupt vectors 32 to 47, exactly like the PIT, and the transfer of legacy IRQs management from the PIT to the IOAPIC. + +It's operated by `sh_gsi_irq_switch()`. This is the only function that is allowed to call `sh_irq_switch_irq_management()`. By default, all the IOREDTBL entries corresponding to the GSI lines used by all legacy IRQs will be mask. diff --git a/docs/shelter/irq/idt.md b/docs/shelter/irq/idt.md new file mode 100644 index 0000000..7127658 --- /dev/null +++ b/docs/shelter/irq/idt.md @@ -0,0 +1,49 @@ +# IDT generation and loading + +The IDT management is defined inside `shelter/lib/include/irq/idt.h` and implemented inside `shelter/lib/src/irq/idt.c`. The current IDT generator generate the IDT according to boot process needs, and is therefore not definitive. + +## IDT generation + +The IDT entry is structured with this structure: +``` C +#pragma pack(1) +typedef struct { + sh_uint16 offset_low; + sh_uint16 selector; + sh_uint8 ist; + sh_uint8 type_attr; + sh_uint16 offset_mid; + sh_uint32 offset_high; + sh_uint32 reserved; +} sh_idt_IDT_ENTRY; +#pragma pack() +``` + +The full IDT is stored in this structure: +``` C +#pragma pack(1) +typedef struct { + sh_idt_IDT_ENTRY entries[256]; +} sh_idt_IDT; +#pragma pack() +``` + +IDT entries are generated using the following functions: +- `sh_idt_fill_type_attr_byte(sh_bool present,sh_uint8 dpl,sh_uint8 type)`: generate the `type_attr` byte +- `sh_idt_fill_idt_entry(sh_uint64 offset,sh_uint16 selector,sh_uint8 ist,sh_uint8 type_attr)`: generate an IDT entry, expect the `type_attr` argument as `sh_idt_fill_type_attr_byte()` would generate it + +The IDT is generated by `sh_idt_fill_idt(sh_idt_IDT *idt)`. + +Using the following structure: +``` C +#pragma pack(1) +typedef struct { + sh_uint16 limit; + sh_uint64 base; +} sh_idt_IDTR; +#pragma pack() +``` + +`sh_idt_load_idtr(sh_idt_IDT *idt)` load the IDT. + +The following vectors are filled for the moment: 0 to 21, 28 to 30, 32 to 47, 254 and 255. Please see the [IRQ docs](irq.md) to see how the handlers work. diff --git a/docs/shelter/irq/index.md b/docs/shelter/irq/index.md new file mode 100644 index 0000000..ae90d2f --- /dev/null +++ b/docs/shelter/irq/index.md @@ -0,0 +1,19 @@ +# IRQ subsystem + +## Introduction + +The IRQ subsystem contains all things related to interrupts management. + +## Overview + +The IRQ subsystem manages the following elements: +- [TSS structure generation and loading](tss.md) +- [GDT generation for bootstrap and applications processors, and GDT loading](gdt.md) +- [IDT generation and loading](idt.md) +- [IRQ handlers](irq.md) +- [ISO registering and GSI abstractions](gsi.md) + +Please note the following: +- this subsystem is only targeting the x86-64 architecture +- this subsystem should only be used after the full memory subsystem initialization +- all the assets generated by this subsystem is, for the moment, only useful for the task performed during the boot process diff --git a/docs/shelter/irq/irq.md b/docs/shelter/irq/irq.md new file mode 100644 index 0000000..0f9ec93 --- /dev/null +++ b/docs/shelter/irq/irq.md @@ -0,0 +1,126 @@ +# IRQ handlers + +The current IRQ handlers are defined in `shelter/lib/include/irq/irq.h` and implemented in `shelter/lib/src/irq/irq.c`. The current handlers are tailored to fit the needs of the boot process and are therefore not complete at all. + +## Overview + +All IRQ handling is done through the macros defined inside `shelter/lib/src/irq/irq_handler.asm`. + +The current IRQ handlers are currently capable of managing three categories: +- CPU faults +- Legacy IRQs +- LAPIC interrupts + +The main dispatching is done inside `sh_irq_dispatch(sh_irq_INTERRUPT_FRAME *frame)`. The `frame` argument is built by pushing registers on the stack in the ASM stub and look like this: +``` C +typedef struct { + sh_uint64 r11,r10,r9,r8,rdx,rcx,rax; + sh_uint64 vector; + sh_uint64 error_code; + sh_uint64 rip; + sh_uint64 cs; + sh_uint64 rflags; +} sh_irq_INTERRUPT_FRAME; +#pragma pack() +``` + +This frame will probably be modified/expanded in futures updates. + +When we say "block", we mean a simple infinite loop. + +## CPU faults + +The following table provide the informations related to CPU faults handling: + +Name | Behaviour +-----|---------- +Division by zero | Log and block +Debug | Log and block +NMI | Log and block +Breakpoints | Log and continue, usage of breakpoints isn't supported but it won't block the kernel +Overflow | Log and block +Bound range | Log and block +Device not available | Log and block +Double fault | Log and block +Co-processor segment overrun | Log and block +Invalid TSS | Log and block +Segment not present | Log and block +Stack segment fault | Log and block +General protection fault | Log and block +Page fault | Log and block +Alignement check | Log and block +Machine check | Log and block +SIMD floating point exception | Log and block +Virtualization exception | Log and block +Control protection exception | Log and block +Hypervisor exception exception | Log and block +VMM communication exception | Log and block +Security exception | Log and block + +CPU faults are the only exception where the frame will be presented. + +## Legacy IRQs + +In Shelter, legacy IRQs are remapped on vectors 32 to 47. Depending on vector, two behavious are possibles: +- If vector is 32, the IRQ come from the PIT, starting a specific procedure depending on the context +- If vector is between 33 and 47, the IRQ is treated by registered IRQ handlers + +Legacy IRQs have two main state: +- Managed by PIC: in this case, they are just logged and then ignored, except for the PIT IRQ0 depending on the context +- Managed by IOAPIC: in this case, PIT IRQ0 are logged and then ignored, and others IRQ are delegated to drivers handlers + +The switch between PIC and IOAPIC is effectuated by `sh_irq_switch_irq_management()`. Only after this switch is correctly done, drivers handles can be registered using `sh_irq_legacy_register_handler(sh_uint8 legacy_irq,sh_irq_HANDLER_PTR handler)`. Handlers can't be registered for IRQ 0. Once a handler is set, it can't be removed or updated. The `sh_irq_legacy_register_handler()` function automatically unmask the GSI corresponding to the legacy IRQ. + +The type `sh_irq_HANDLER_PTR` is defined like this: +``` C +typedef void (*sh_irq_HANDLER_PTR)(); +``` + +No arguments are provided. + +### PIT IRQ + +The PIT is mainly used to estimate the CPU frequency. For this, each PIT IRQ is handled differently depending on the context. + +The `sh_irq_start_tsc()` function signal to the IRQ handler that the CPU frequency estimation procedure has been triggered, setting the internal state of the procedure to 0, and reseting the TSC values (`tsc_start`, `tsc_end` and `tsc_delta`). + +When a PIT IRQ arrives: +- If the legacy IRQs are managed by IOAPIC, simply log and continue +- If not, do the following: + - If the state of the estimation procedure is 0, set `tsc_start` to the current TSC register value and set the state of the procedure to 1 + - Else if the state of the estimation procedure is 1, set `tsc_end` to the current TSC register value, compute `tsc_delta = tsc_end - tsc_start` and set the state of the procedure to 2 + - Else, log and continue + +The `sh_irq_get_tsc_delta()` return `tsc_delta`. A value of 0 indicating that the procedure isn't finished yet. + +### Others legacy IRQs + +Others legacy IRQs (vectors 33 to 47) are handled through a common loader that work like this: +- If the legacy IRQs are managed by IOAPIC: + - If a handler pointer is defined for this legacy IRQ, call it and continue once finished + - Else, just continue without logging +- Else, log and block + +## LAPIC interrupts + +LAPIC interrupts can be of two sorts: +- one shot timer: mapped on vector 254 +- spurious vector: mapped on vector 255 + +### One shot timer + +The purpose of this handler is to know when the one shot timer generated an interrupt. + +Each CPU maintain in its per-CPU struct a boolean named `timer_state.` + +The `sh_irq_start_timer()` function is executed by the function to arm the `timer_state` flag: it set this flag to `SH_TRUE`. + +When an one shot timer interrupt arrives: +- If `timer_state` was `SH_FALSE`, log the interrupt for debug purposes, it doesn't block anything +- If `timer_state` was `SH_TRUE`, set it to `SH_FALSE` and then resume + +The `sh_irq_get_timer_state()` function is a wrapper that return the local `timer_state` of any CPU. + +### Spurious vector + +In case of interrupts on the spurious vector, we just log it for debug purposes and continue. diff --git a/docs/shelter/irq/tss.md b/docs/shelter/irq/tss.md new file mode 100644 index 0000000..28ee9f1 --- /dev/null +++ b/docs/shelter/irq/tss.md @@ -0,0 +1,11 @@ +# TSS structure generation and loading + +The TSS management is defined in `shelter/lib/include/irq/tss.h` and implemented in `shelter/lib/include/irq/tss.c`. + +This implementation provides the following types: +- `sh_tss_TSS`: a full structure of a 64 bits TSS +- `sh_tss_TR`: a structure used to load the TSS + +The following functions are provided: +- `sh_tss_fill_tss(sh_tss_TSS *tss)`: fill a TSS structure with 4 stacks dedicated for double faults, NMI, page faults and stack-related faults. Heap must be available for using this function. All stacks are 4 pages long +- `sh_tss_load_tr(sh_tss_TSS* tss)`: load the provided TSS into the task register. Always assume that the TSS selector in the GDT is `0x28` diff --git a/docs/shelter/kernel/efifb.md b/docs/shelter/kernel/efifb.md new file mode 100644 index 0000000..d332d35 --- /dev/null +++ b/docs/shelter/kernel/efifb.md @@ -0,0 +1,18 @@ +# EFI framebuffer + +## Introduction + +This subsystem aims to provide a simple way to indicate the boot process state using a progress bar displayed on the EFI GOP framebuffer. For the moment, only framebuffers using 32 bits pixel format are supported. It's defined in `shelter/lib/include/kernel/efifb.h` and implemented in `shelter/lib/src/kernel/efifb.c`. + +## Overview + +To avoid any complex colors encoding, pixel values for the colors white and gray must be provided through the framebuffer configuration. + +The framebuffer parameters are loaded using the `sh_efifb_init_fb(sh_conf_FB_CONFIG *fb_conf,sh_page_PAGE_TABLE_POOL *ptp)` function. This function will: +1) Load framebuffers dimensions +2) Identity map the whole framebuffers +3) Erase the previous texts on the framebuffer, based on the information provided in the framebuffer configuration + +The progress bar is initialized using `sh_efifb_init_bar()`. It will draw an empty progress bar. + +Finally, to update the progress bar, the `sh_efifb_set_bar(sh_uint8 percent)` function is used. diff --git a/docs/shelter/kernel/kernel.md b/docs/shelter/kernel/kernel.md index 5c81b48..1cb5e49 100644 --- a/docs/shelter/kernel/kernel.md +++ b/docs/shelter/kernel/kernel.md @@ -9,3 +9,4 @@ The Shelter kernel define his own specific APIs like logging and configuration p 1) [Log API](log.md) 2) [Config parsing](config.md) 3) [Tests utilities](testutils.md) +4) [EFI framebuffer](efifb.md) diff --git a/docs/shelter/kernel/log.md b/docs/shelter/kernel/log.md index 41d20d9..d8cf320 100644 --- a/docs/shelter/kernel/log.md +++ b/docs/shelter/kernel/log.md @@ -2,7 +2,7 @@ ## Introduction -The logging API is one of the most important of the entire kernel: it allow it to output informations with various level of importance and various sources. +The logging API is one of the most important of the entire kernel: it allow it to output informations with various level of importance and various sources, during the early boot period. After the APs bootstrap, the log API is replaced by the print implementation provided by the standard library, because it is thread safe. ## Output methods @@ -35,7 +35,7 @@ There are two mores functions: ## Output channels and log level -The Shelter logging API provide higher level functions to output on specific log channels. Here are all the log channels: +The Shelter logging API provides higher level functions to output on specific log channels. Here are all the log channels: - `SH_LOG_DEBUG`: log level 0 - `SH_LOG_LOG`: log level 1 - `SH_LOG_WARNING`: log level 2 @@ -43,6 +43,7 @@ The Shelter logging API provide higher level functions to output on specific log - `SH_LOG_CRITICAL`: log level 4 - `SH_LOG_FATAL`: log level 5 - `SH_LOG_TEST`: log level 6 +- `SH_LOG_FAULT`: log level 7 Each log channel has a log level. The log level is set by the `log_level` boot configuration key. The log API will only output log messages with log level equal or higher to current log level. This restriction doesn't apply to log channel `SH_LOG_TEST`. @@ -69,7 +70,7 @@ The `sh_log_OUTPUT_SOURCE` type is used to store log source. It's a wrapper of ` ## Output payloads -In order to compile all of those informations into one payload, the logging API provide this structure : +In order to compile all of those informations into one payload, the logging API provides this structure : ``` C typedef struct { sh_log_OUTPUT_TYPE output_type; @@ -115,7 +116,7 @@ They all need two arguments in the following order (except `sh_log_ltest` which ### Logging with formating -In order to allow for formatting log messages, the log API provide functions named like this: +In order to allow for formatting log messages, the log API provides functions named like this: ``` sh_log_f[test/debug/log/warning/error/critical/fatal] ``` diff --git a/docs/shelter/memory/index.md b/docs/shelter/memory/index.md index 0570514..b155f17 100644 --- a/docs/shelter/memory/index.md +++ b/docs/shelter/memory/index.md @@ -2,7 +2,7 @@ ## Introduction -The memory subsystem is responsible for handling tasks like physical pages allocations, virtual memory management, initial memory map analysis, pages mapping and unmapping and kernel heap management. +The memory subsystem is responsible for handling tasks like physical pages allocations, virtual memory management, initial memory map analysis, pages mapping and unmapping and kernel heap management. Please note that, unless used with `sh_malloc` or `sh_free`, no object or function described in this subsystem is thread safe. ## Summary @@ -14,3 +14,12 @@ The memory subsystem is responsible for handling tasks like physical pages alloc 6) [Radix trees subsystem](radix.md) 7) [Pez plane manager](pez.md) 8) [Kernel heap manager](heap.md) + +## Memory subsystem + +The memory subsystem is defined into `shelter/lib/include/memory/memory.h` and implemented into `shelter/lib/include/memory/memory.c`. + +The entire memory subsystem is initialized with the `sh_memory_init_subsystem()` function. This function produces a `sh_memory_MEMORY_SERVICES` struct, which is stored in the main file and contains all the elements necessary for the memory subsystem initialization. + +The memory subsystem also provides some higher level functions: +- `sh_memory_identity_map(sh_page_PHYSICAL_ADDRESS phys_start,sh_uint64 page_count,sh_uint64 flags)`: identity map a range of physical pages into the page table of the booting kernel. It is not thread safe. diff --git a/docs/shelter/memory/page.md b/docs/shelter/memory/page.md index f827fc0..3d1e90e 100644 --- a/docs/shelter/memory/page.md +++ b/docs/shelter/memory/page.md @@ -85,6 +85,9 @@ This role of memory allocations is lost once Pez is initialized. The Page subsystem provide the following functions regarding memory statistics: - `sh_uint64 sh_page_get_physical_memory_amount_pages()`: return amount of physical memory installed in pages - `sh_uint64 sh_page_get_physical_memory_amount_bytes()`: return amount of physical memory installed in bytes +- `sh_uint64 sh_page_get_installed_memory_bytes()`: return the amount of physical memory in pages counted as free when parsing the memory map - `SH_STATUS sh_page_get_memory_stats(sh_page_MEM_STATS *mem_stats)`: provide a extensive amount of statistics on physical memory. -For a more human-readable output, the function `sh_log_mem_stats` can be used. +For a more human-readable output, the function `sh_log_mem_stats` can be used for debugging purposes. It doesn't rely on Pez. + +When Pez is ready, please uses instead the DevS memory subsystem endpoint, it's faster and refined. diff --git a/docs/shelter/memory/ring.md b/docs/shelter/memory/ring.md index 349d2b6..5ff6453 100644 --- a/docs/shelter/memory/ring.md +++ b/docs/shelter/memory/ring.md @@ -6,6 +6,6 @@ The memory subsystem provide a simple ring buffer API, mainly used by the log AP ## Overview -The main structure for a ring buffer is `sh_ring_RING_BUFFER_HEADER`. The function provided by the API are volontary very simple for the moment: +The main structure for a ring buffer is `sh_ring_RING_BUFFER_HEADER`. The function provided by the API are volontarily very simple for the moment: - `SH_STATUS sh_ring_write_byte(sh_ring_RING_BUFFER_HEADER *ring_buffer,sh_uint8 byte)`: write a byte inside provided ring buffer - `SH_STATUS sh_ring_write_string(sh_ring_RING_BUFFER_HEADER *ring_buffer,char *string)`: write a null-terminated string inside provided ring buffer diff --git a/docs/shelter/naming.md b/docs/shelter/naming.md index 1157e61..246348d 100644 --- a/docs/shelter/naming.md +++ b/docs/shelter/naming.md @@ -1,11 +1,13 @@ # Naming scheme Shelter has a very specific way of organizing subsystems. -First, each part of the kernel (except `main.c` which is responsible for the boot process) is in his own folder. To this date, there is 4 main parts: +First, each part of the kernel (except `main.c` which is responsible for the boot process) is in his own folder. To this date, there is 6 main parts: - `cpu`: CPU abstractions - `kernel`: kernel services - `std`: Shelter standard library - `memory`: the whole memory subsystem +- `irq`: all thing IRQ-related (GDT, TSS, IDT, IRQ handler and GSI) +- `devs`: all things devices-related, including drivers, Device System API and ACPI parsers Then, each of these parts have specific subsystem or API prefix. These prefixes always start by `sh_` and doesn't include the part each subsystem or API is in. For exemple, the serial outputing API prefix is `sh_serial_`. diff --git a/docs/shelter/ptp.md b/docs/shelter/ptp.md index 45d0722..7a03232 100644 --- a/docs/shelter/ptp.md +++ b/docs/shelter/ptp.md @@ -2,7 +2,7 @@ ## Introduction -In order to easely manage pages that are used for pages tables (PT), the Vystem project use pages tables pool (PTP). For details about mapping the PTP inside the kernel virtual memory space, please see [boot contract docs](bootcontract.md). +In order to easily manage pages that are used for pages tables (PT), the Vystem project use pages tables pool (PTP). For details about mapping the PTP inside the kernel virtual memory space, please see [boot contract docs](bootcontract.md). ## Overview @@ -20,4 +20,4 @@ PTP, when created from the bootloader, are mapped within themself read-write and The purpose of any PTP is to have a reserved amount of pages to permit the quick allocation of single page to allow any mapping. There is two kinds of allocator, depending on the needs of the situation: - bumb/counter allocator: here, we simply increment a counter that represent an index inside the pages range of the PTP, allowing for very quick PTP initialization. Intended for PTP creation and mapping without unmapping by the program creating the PTP. This is the kind of allocator used into the Blastproof bootloader -- bitmap allocator: a bitmap for storing which pages of the pages range is allocated or not. Intended when heavy unmapping is made, to free pages more easely. This is the allocator used in the Shelter Kernel. It can be initialized from the counter value, passed by the bootloader for example. For the moment, automatic pages freeing from the page table isn't implemented. +- bitmap allocator: a bitmap for storing which pages of the pages range is allocated or not. Intended when heavy unmapping is made, to free pages more easily. This is the allocator used in the Shelter Kernel. It can be initialized from the counter value, passed by the bootloader for example. For the moment, automatic pages freeing from the page table isn't implemented. diff --git a/docs/shelter/std/malloc.md b/docs/shelter/std/malloc.md index a48eeea..1352a8a 100644 --- a/docs/shelter/std/malloc.md +++ b/docs/shelter/std/malloc.md @@ -1,7 +1,9 @@ # Heap memory allocations -The Shelter standard library provide a single API for memory allocations on the heap. The heap is only initialized at the end of the memory subsystem and can't be used before. It's not adapted for memory mapped I/O or big buffers allocations (larger than one hundrer pages). The heap internal documentation can be found inside the memory subsystem documentation. +The Shelter standard library provide a single API for memory allocations on the heap. The heap is only initialized at the end of the memory subsystem and can't be used before. It's not adapted for memory mapped I/O or big buffers allocations (roughly than one hundred pages). The heap internal documentation can be found inside the memory subsystem documentation. The memory allocations API provide the two following functions (defined inside `shelter/lib/include/std/malloc.h` and implemented inside `shelter/lib/src/std/malloc.c`): - `void* sh_malloc(sh_uint64 size)`: allocate `size` amount of bytes. Return `SH_NULLPTR` if an error occured. The heap internal will trigger a heap crash (essentially a `while (SH_TRUE)` loop) to prevent any further damage if something very bad happen. - `void sh_free(void *ptr)`: free the memory allocated at `ptr`. The heap internal will trigger a heap crash (essentially a `while (SH_TRUE)` loop) to prevent any further damage if something very bad happen. + +To prevent any race conditions, there is a global lock on the entry point of the heap in the standard library. After APs bootstrap, only those entry point should be used for basic memory allocation. diff --git a/docs/shelter/std/mem.md b/docs/shelter/std/mem.md index 268f81c..bfa07c4 100644 --- a/docs/shelter/std/mem.md +++ b/docs/shelter/std/mem.md @@ -1,6 +1,6 @@ # Basic memory operations -The Shelter standard library provide very basic memory operations primitives, defined in `shelter/lib/include/std/mem.h` and implemented inside `shelter/lib/src/std/mem.c`: +The Shelter standard library provides very basic memory operations primitives, defined in `shelter/lib/include/std/mem.h` and implemented inside `shelter/lib/src/std/mem.c`: - `SH_STATUS sh_mem_compare(const void *a,const void *b,sh_uint64 size)`: compare two memory regions with the same size. Return `SH_STATUS_SUCCESS` if both regions are equal, or `SH_STATUS_MEM_NOT_EQUAL` if one byte is different. - `SH_STATUS sh_mem_copy(const void *destination,const void *source,sh_uint64 size)`: copy one region of memory to another. Return `SH_STATUS_SUCCESS` - `SH_STATUS sh_mem_set_8(sh_uint8 *ptr,const sh_uint8 byte,sh_uint64 count)`: set a provided amount of bytes to the value of one provided byte. Return `SH_STATUS_SUCCESS` diff --git a/docs/shelter/std/print.md b/docs/shelter/std/print.md new file mode 100644 index 0000000..92ebd5b --- /dev/null +++ b/docs/shelter/std/print.md @@ -0,0 +1,53 @@ +# Print primitives + +## Introduction + +The standard library provides his own abstraction to print strings. This abstraction can be used before the APs bootstrap and must be used after the APs bootstrap. The print implementation in the standard library is fully thread-safe. The print implementation is defined inside `shelter/lib/include/std/print.h` and implemented inside `shelter/lib/include/std/print.c`. + +The format syntax is the same used in the kernel logging API. See [format syntax](../kernel/log.md). + +## Print initialization + +Before the initialization of the print implementation, all output using `sh_print` and `sh_printf` is redirected to the kernel logging API. + +The initialization of the print implementation is done through `sh_print_setup_ring_buffers_per_ap()`. This function initializes a ring buffer for each CPU, including the bootstrap CPU. The size of each ring buffer is the amount of bytes for the global logging ring buffer divided by the amount of CPU. + +Every single print primitives (except `sh_sprintf`, which doesn't print anything) respect the log level specified in the kernel boot configuration. + +## Characteristics + +This print implementation differ of the kernel logging API by these differences: +- It doesn't support displaying the name of the subsystem +- It shows the logical CPU id of the AP that called the print implementation + +It also defines its own macros for the type of output: `SH_DEBUG`, `SH_LOG`, `SH_WARNING`, `SH_ERROR`, `SH_CRITICAL`, `SH_FATAL`, `SH_TEST`, `SH_FAULT` + +## Normal printing + +### API + +The print implementation provide two functions for normal printing: +- `sh_print(sh_log_OUTPUT_TYPE output_type,char *text)`: print a normal string without formatting the text before hand +- `sh_printf(sh_log_OUTPUT_TYPE output_type,char* format,...)`: format and print the formatted string byte by byte + +### Detailled processus + +For normal printing, the outputed text goes through two main steps: + +First, each byte is outputed into the local printing ring buffer. We keep track of the amount of bytes outputed using the attribute in the per-CPU struct of this CPU. + +Then, extracting the outputed byte from the local printing ring buffer, all outputed bytes are sent to the serial port, no without locking a global serial spinlock before. + +## Interrupts printing + +The print system also provides a dedicated path for interrupt handlers. In this mode, output bypasses the local ring buffer and is written directly to the serial port after acquiring the serial spinlock. If the lock is already held by another CPU, the function will block until it becomes available. + +The API is as follows: +- `sh_iprint(sh_log_OUTPUT_TYPE output_type,char *text)`: same as `sh_print` but for interrupt handlers +- `SH_STATUS sh_iprintf(sh_log_OUTPUT_TYPE output_type,char* format,...)`: same as `sh_iprintf` but for interrupt handlers + +## String formatting + +Finally, the print implementation provides a way to easely format strings using the same format syntax, using `sh_sprintf(char *output_string,sh_uint64 output_len,char *format,...)`. + +This function writes into the provided buffer only. It doesn't print to the serial port, doesn't use ring buffers, and doesn't allocate memory via `sh_malloc`. diff --git a/docs/shelter/std/queues.md b/docs/shelter/std/queues.md new file mode 100644 index 0000000..7322086 --- /dev/null +++ b/docs/shelter/std/queues.md @@ -0,0 +1,23 @@ +# Queues + +## Introduction + +The standard library provides various queues implementations for various objects sizes. Queue objects aren't thread safe. It is defined inside `shelter/lib/include/std/queue.h` and implemented in `shelter/lib/src/std/queue.c`. + +## Keyboard events queue + +This queue is represented by the following object: +``` C +typedef struct { + sh_kbd_EVENT *buffer; + sh_uint32 capacity; + sh_uint32 write_index; +} sh_queue_KBD_EVENT; +``` + +These queues automatically overwrite the oldest object when the caller try to push an object when the queue is full. + +The API is as follows: +- `sh_queue_event_init(sh_queue_KBD_EVENT *q,sh_uint32 capacity)`: initialize a keyboard events queue, allocate the queue buffer +- `sh_queue_event_push(sh_queue_KBD_EVENT *q,sh_kbd_EVENT ev)`: push an event into the provided queue +- `sh_queue_event_destroy(sh_queue_KBD_EVENT *q)`: destroy the provided queue, free the queue buffer diff --git a/docs/shelter/std/smp.md b/docs/shelter/std/smp.md new file mode 100644 index 0000000..0dd8e87 --- /dev/null +++ b/docs/shelter/std/smp.md @@ -0,0 +1,54 @@ +# SMP services + +## Introduction + +The SMP services provide various abstractions related to SMP programming. It is defined inside `shelter/lib/include/std/smp.h` and implemented in `shelter/lib/src/std/smp.c` + +## GS register + +Regarding the GS register, two functions are provided: +- `sh_smp_write_gs_base(sh_uint64 value)`: Write the `IA32_GS_BASE` MSR. with a value, return nothing +- `sh_smp_gs_base()`: take no argument and return a `sh_ap_CPU_STRUCT*` + +## Spinlocks + +The SMP services provide a basic implementation for a spinlock, which look like this: + +``` C +typedef struct { + volatile sh_uint32 spinlock; + sh_uint32 lapic_id; +} sh_SPIN_LOCK; +``` + +Two macros are provided to initialize an unlocked spinlock: +- `SH_LOCK()`: intended for spinlocks stored as global variables +- `SH_LOCK_LOCAL()`: intended for spinlocks stored as local variables or into structs + +This spinlock implementation requires `sh_smp_gs_base()` to return a valid pointer to a CPU struct. It uses the atomics primitives provided by compilers. Spinlock operations provide full memory ordering guarantees. + +Four functions are provided for spinlock manipulation: +- `sh_spin_lock(sh_SPIN_LOCK *lock)`: lock a spinlock, block until the lock is acquired. Return nothing +- `sh_spin_unlock(sh_SPIN_LOCK *lock)`: unlock a spinlock, return nothing +- `sh_spin_trylock(sh_SPIN_LOCK *lock)`: Attempt to acquire the lock without blocking., return `SH_TRUE` if successfull, `SH_FALSE` otherwise. +- `sh_spin_wholock(sh_SPIN_LOCK *lock)`: return the LAPIC id of the CPU locking the spinlock. Return `SH_UINT32_MAX` if the spinlock isn't owned by any CPU + +Current implementation doesn't disable interrupts while holding locks. + +## CPU count + +SMP services can store the amount of CPU cores using the following functions: +- `sh_smp_set_cpu_count(sh_int16 cpu_count)`: set the count of CPU. It is only called one time by `sh_ap_prepare_for_smp_launch()` +- `sh_smp_get_cpu_count()`: return the count of CPU, return `-1` if value isn't initialized + +## Memory barrier + +The SMP services provide the following primitives: + +Function name | Role +--------------|----- +`sh_mb()` | Full memory barrier +`sh_rmb()` | Read memory barrier +`sh_wmb()` | Write memory barrier + +Current x86_64 implementation uses mfence/lfence/sfence. diff --git a/docs/shelter/std/std.md b/docs/shelter/std/std.md index e6265c9..8ec0c18 100644 --- a/docs/shelter/std/std.md +++ b/docs/shelter/std/std.md @@ -10,5 +10,9 @@ In order to function properly, any kernel need a standard library. Shelter defin 2) [Return status](status.md) 3) [Basic memory operations](mem.md) 4) [Heap memory allocations](malloc.md) +5) [Print primitives](print.md) +6) [String operations](strings.md) +7) [SMP services](smp.md) +8) [Queues](queues.md) You can include the file `shelter/lib/include/std/stdlib.h` to include all necessary headers to access the Shelter standard library. diff --git a/docs/shelter/std/strings.md b/docs/shelter/std/strings.md new file mode 100644 index 0000000..56f8aba --- /dev/null +++ b/docs/shelter/std/strings.md @@ -0,0 +1,9 @@ +# Strings operations + +The Shelter standard library provides basic strings operations primitives, defined in `shelter/lib/include/std/string.h` and implemented inside `shelter/lib/src/std/string.c`: +- `sh_string_len(char *str)`: return the length of a null terminated string +- `sh_string_compare(char *str1,char* str2,sh_uint64 length)`: compare two null terminated string, both strings must not exceed the provided length. return `SH_TRUE` if both strings are equal on the provided length +- `sh_string_find_char(char *str,char character)`: return the index of the first occurence of the provide character into the string, return `SH_UINT64_MAX` if not found or error +- `sh_string_find(char *str,char *substr)`: return the index of the start of the first occurence of the provided substring into the string, return `SH_UINT64_MAX` if not found or error +- `sh_string_substring(char *source_str,sh_uint64 start_index,sh_uint64 length,char *output)`: copy a substring from a string to another string, and return the pointer to the new null terminated string (aka the provided `output` pointer). Return `SH_NULLPTR` if error +- `sh_string_to_uint64(char *str)`: convert a string to a `sh_uint64` and return this `sh_uint64` diff --git a/docs/shelter/tab.md b/docs/shelter/tab.md index b3a8bf0..c1f9423 100644 --- a/docs/shelter/tab.md +++ b/docs/shelter/tab.md @@ -43,7 +43,7 @@ The test will separate single page allocations and frees from multi-pages alloca ## Malloc subsystem test -These tests are design to test the reliability and performances of the Pez subsystem. They are defined inside `shelter/lib/include/kernel/tests/test_malloc.h` and implemented inside `shelter/lib/src/kernel/tests/test_malloc.c`. They use the `shelter/lib/src/kernel/tests/payloads/test_malloc_payload.h`. +These tests are designed to test the reliability and performances of the Pez subsystem. They are defined inside `shelter/lib/include/kernel/tests/test_malloc.h` and implemented inside `shelter/lib/src/kernel/tests/test_malloc.c`. They use the `shelter/lib/src/kernel/tests/payloads/test_malloc_payload.h`. The payload contain the following datas: - `test_malloc_small_size`: contain 10000 sizes for small allocations (under or equal to 1024 bytes) @@ -51,3 +51,9 @@ The payload contain the following datas: - `test_malloc_big_alloc`: contain 2000 values, serving the same role and generated like `test_pez_physical_alloc` The malloc test combine two tests: 10000 allocations and deallocations of variously sized small objects using the generic slab allocators, and 1000 allocations and frees of pages on the heap, on the same logic of the Pez subsystem test, but adapted to the quantity used in this test. + +## Queues tests + +This test is mainly designed to stress test the queue implementation provided by the standard library. + +It simply consists of 10000 objects pushed into a queue. diff --git a/docs/vybuild/actions.md b/docs/vybuild/actions.md new file mode 100644 index 0000000..57e467c --- /dev/null +++ b/docs/vybuild/actions.md @@ -0,0 +1,1070 @@ +# Actions + +## Introduction + +Actions are atomic blocks of the pipeline. They are used for all sorts of things such as compiling, filesystem manipulation, control flow, cache management and command execution. Please note that things related to VFTM aren't documented in this documentation. + +## Syntax + +Actions are listed in the `actions` field of each module. They are executed in the order they are specified, without any automatic reordering. +Actions all follow at their cores the same syntax: + +``` json + { + "action":"...", + "args":{ + ... + } + } +``` + +The `action` field specify the name of the action to execute and the `args` field specify all sorts of arguments, specific to each actions. + +## List of all available actions + +### Commands related actions + +**Note:** There is, for the moment, no action capable of combining the saving of output of a command with a working directory for example + +#### `run_command_wait` + +The `run_command_wait` action allows you to run a command and wait for it to finish. If the command fail, the action and therefore the entire module fail, interrupting the build process. It can be used in multithreaded build pipelines without restriction. + +Syntax: + +``` json + { + "action":"run_command_wait", + "args":{ + "command_variables":..., + "command":[ + ... + ], + "show_output":..., + "success_status":[ + ... + ], + "ignore_success_status":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|-----------------|----------------------- +`command_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `command` argument. +`command` | list of strings | anything | The list of arguments that will be passed to the `execvp` function. The first element is considered as the name of the executable, and should be either accessible in PATH or from the indicated `root_folder` of the module. +`show_output` | string | `live`, `on_failure` or `silent` | Indicate how the output of the command should be shown. Uses `live` if your command require user input in the console. Failure detection is based on output codes of the processus. +`success_status` | list of integers | any integers | Indicate the integers that should be considered as a success of the command. If the output code of the command isn't in this list, the command is considered as failed. +`ignore_success_status` | boolean | `true` or `false` | If this field is `true`, no output code will fail the action. + +#### `run_command_wait_dir` + +The `run_command_wait_dir` action behave exactly as the `run_command_wait` action, except it allows you to provide a path in which VyBuild will `chdir` before executing the command. It can be used in multithreaded build pipelines without restriction. + +Syntax: + +``` json + { + "action":"run_command_wait_dir", + "args":{ + "command_variables":..., + "command":[ + ... + ], + "success_status":[ + ... + ], + "ignore_success_status":..., + "show_output":..., + "working_dir_variables":..., + "working_dir":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|-----------------|----------------------- +`command_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `command` argument. +`command` | list of strings | anything | The list of arguments that will be passed to the `execvp` function. The first element is considered as the name of the executable, and should be either accessible in PATH or from the indicated `working_dir` argument. +`show_output` | string | `live`, `on_failure` or `silent` | Indicate how the output of the command should be shown. Uses `live` if your command require user input in the console. Failure detection is based on output codes of the processus. +`success_status` | list of integers | any integers | Indicate the integers that should be considered as a success of the command. If the output code of the command isn't in this list, the command is considered as failed. +`ignore_success_status` | boolean | `true` or `false` | If this field is `true`, no output code will fail the action. +`working_dir_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `working_dir` argument. +`working_dir` | string | any valid path | Indicate the working directory in which VyBuild should `chdir` before executing the command. + +#### `save_command_content` + +The `save_command_content` behave exactly like the `run_command_wait` action, except instead of showing the output, it save it into a file. It can be used in multithreaded build pipelines without restriction. + +Syntax: + +``` json + { + "action":"save_command_content", + "args":{ + "command_variables":..., + "command":[ + ... + ], + "success_status":[ + ... + ], + "ignore_success_status":..., + "command_output_file_variables":..., + "command_output_file":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|-----------------|----------------------- +`command_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `command` argument. +`command` | list of strings | anything | The list of arguments that will be passed to the `execvp` function. The first element is considered as the name of the executable, and should be either accessible in PATH or from the indicated `working_dir` argument. +`success_status` | list of integers | any integers | Indicate the integers that should be considered as a success of the command. If the output code of the command isn't in this list, the command is considered as failed. +`ignore_success_status` | boolean | `true` or `false` | If this field is `true`, no output code will fail the action. +`command_output_file_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `command_output_file` argument. +`command_output_file` | string | any valid path | Indicate the file in which the output of the command should be saved. The previous content of the file is erased. The parent directory of the file must exists. + +#### `run_command_str_wait` + +The `run_command_str_wait` behave exactly like the `run_command_wait` action, except that instead of providing the command in a list of arguments, they are provided as a single string that is then processed with `wordexp`, which parse them nearly exactly as a shell would do. The variables replacement is ran before the `wordexp` call. It can be used in multithreaded build pipelines without restriction. + +``` json + { + "action":"run_command_str_wait", + "args":{ + "command_variables":..., + "command":..., + "success_status":[ + ... + ], + "ignore_success_status":..., + "show_output":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|-----------------|----------------------- +`command_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `command` argument. +`command` | string | anything | The string that will be parsed by `wordexp` and then fed into `execvp`. The first element of the parsing result is considered as the name of the executable, and should be either accessible in PATH or from the indicated `root_folder` of the module. +`show_output` | string | `live`, `on_failure` or `silent` | Indicate how the output of the command should be shown. Uses `live` if your command require user input in the console. Failure detection is based on output codes of the processus. +`success_status` | list of integers | any integers | Indicate the integers that should be considered as a success of the command. If the output code of the command isn't in this list, the command is considered as failed. +`ignore_success_status` | boolean | `true` or `false` | If this field is `true`, no output code will fail the action. + +### Compilation related actions + +The `compile_one_*` action are safe and authorized in multithreaded pipelines, but `compile_multiple_cpp`and `vyld_compilation` can only be used in parts of pipelines that aren't in a multithreaded phase. + +#### `compile_one_asm` + +The `compile_one_asm` action, as its name imply, compile a single assembly file. It is intended for simple and single compilation operation. It can be used in multithreaded build pipelines without restriction. + +Syntax: + +``` json + { + "action":"compile_one_asm", + "args":{ + "source_variables":..., + "source":..., + "assembler_variables":..., + "assembler":..., + "pre_arguments_variables":..., + "pre_arguments":[ + ... + ], + "post_arguments_variables":..., + "post_arguments":[ + ... + ], + "output_file_variables":..., + "output_file":..., + "success_status":[ + ... + ], + "ignore_success_status":..., + "cache_authorized":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|-----------------|----------------------- +`source_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `source` argument. +`source` | string | any valid path | Provide the path (path relative to the `root_folder` field of the module or absolute path) to the file to compile. +`assembler_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `assembler` argument. +`assembler` | string | any valid executable name | Provide the executable name of the assembler to use for this action. It must be an executable accessible in PATH. +`pre_arguments_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `pre_arguments` argument. +`pre_arguments` | list of strings | anything | Indicate the pre arguments to fed into `execvp` +`post_arguments_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `post_arguments` argument. +`post_arguments` | list of strings | anything | Indicate the post arguments to fed into `execvp` +`output_file_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `output_file` argument. +`output_file` | string | any valid path | A path relative to `root_folder` that indicate to VyBuild which file to put into cache or to extract from cache. The parent folder must already exists. +`success_status` | list of integers | any integers | Indicate the integers that should be considered as a success of the command. If the output code of the command isn't in this list, the command is considered as failed. +`ignore_success_status` | boolean | `true` or `false` | If this field is `true`, no output code will fail the action. +`cache_authorized` | boolean | `true` or `false` | Allows VyBuild to extract output file from cache if the compilation context matchs, and to store the output file into the cache + +The compilation context is used to generate a key for the cache. For this action, the compilation context contain: source file content, assembler binary hash, assembler path, assembler pre and post arguments. + +The command is executed using `execvp`. The arguments are concatenated as follows: +1. Resolved compiler path. +2. Pre-arguments (in order). +3. Source file path. +4. Post-arguments (in order). + +The user is responsible to provide any `-o` assembler argument where the assembler require it. This is this limitation that indicate which arguments to put into pre and post arguments. + +#### `compile_one_cpp` + +The `compile_one_cpp` action compiles a single C or C++ source file. It is designed to handle dependency tracking through a dedicated header discovery command, ensuring that the cache is invalidated if any included header file is modified. It can be used in multithreaded build pipelines without restriction. + +Syntax: + +```json + { + "action":"compile_one_cpp", + "args":{ + "source_variables":..., + "source":..., + "compiler_variables":..., + "compiler":..., + "pre_arguments_variables":..., + "pre_arguments":[ + ... + ], + "post_arguments_variables":..., + "post_arguments":[ + ... + ], + "output_file_variables":..., + "output_file":..., + "success_status":[ + ... + ], + "ignore_success_status":..., + "cache_authorized":..., + "headers_command_variables":..., + "headers_command":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|-----------------|----------------------- +`source_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source` argument. +`source` | string | any valid path | Provides the path (relative to `root_folder` or absolute) to the C/C++ file to compile. +`compiler_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `compiler` argument. +`compiler` | string | any valid executable name | Provides the executable name of the compiler (e.g., `gcc`, `g++`, `clang`). Must be accessible in PATH. +`pre_arguments_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `pre_arguments` argument. +`pre_arguments` | list of strings | anything | Arguments to be passed to the compiler before the source file. +`post_arguments_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `post_arguments` argument. +`post_arguments` | list of strings | anything | Arguments to be passed to the compiler after the source file (for example `-o` and the output path). +`output_file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `output_file` argument. +`output_file` | string | any valid path | A path relative to `root_folder` that indicate to VyBuild which file to put into cache or to extract from cache. The parent folder must already exists. +`success_status` | list of integers | any integers | Indicate the integers that should be considered as a success of the command. If the output code of the command isn't in this list, the command is considered as failed. +`ignore_success_status` | boolean | `true` or `false` | If this field is `true`, no output code will fail the action. +`cache_authorized` | boolean | `true` or `false` | Allows VyBuild to use the cache for this action. +`headers_command_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `headers_command` argument. +`headers_command` | string | shell command | A command string used to extract header dependencies. + +To ensure perfect cache integrity, VyBuild must know which headers are included by the source file. The `headers_command` field is executed in a shell. VyBuild automatically provides two internal variables for this command: +- `%sourcefile%`: The path to the source file being compiled +- `%dfile%`: A temporary path where VyBuild expects the dependency information to be written (usually in Makefile format) + +Example for GCC: +`"headers_command": "gcc -MMD -MF %dfile% -E %sourcefile% -o /dev/null"` + +The compilation context used to generate the cache key for this action includes: +- The content of the source file +- The content of all discovered header files (using `headers_command`) +- The compiler binary hash and its system path +- All pre and post arguments + +The command is executed using `execvp`. The arguments are concatenated as follows: +1. Resolved compiler path. +2. Pre-arguments (in order). +3. Source file path. +4. Post-arguments (in order). + +#### `compile_multiple_cpp` + +The `compile_multiple_cpp` action allows for the mass compilation of C and C++ source files. It is the multithreaded engine of VyBuild, capable of handling large sets of files either by explicit listing or via a powerful path completion system. This action automatically manages dependency tracking and caching for each individual file. + +Syntax: +``` json + { + "action":"compile_multiple_cpp", + "args":{ + "source_files_path_completion":..., + "path_completion_source_ext":..., + "path_completion_output_ext":..., + "source_files_variables":..., + "source_files":[ + ... + ], + "compiler_variables":..., + "compiler":..., + "pre_arguments_variables":..., + "pre_arguments":[ + ... + ], + "post_arguments_variables":..., + "post_arguments":[ + ... + ], + "output_files_variables":..., + "output_files":[ + ... + ], + "success_status":[ + ... + ], + "ignore_success_status":..., + "cache_authorized":..., + "headers_command_variables":..., + "headers_command":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|-----------------|----------------------- +`source_files_path_completion` | boolean | `true` or `false` | Enables the automatic discovery of source files using wildcards. +`path_completion_source_ext` | string | e.g., `.cpp` | The extension of source files to look for during path completion. +`path_completion_output_ext` | string | e.g., `.o` | The extension to apply to the generated output files. +`source_files_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_files` list +`source_files` | list of strings | paths | List of source files or directory patterns (if path completion is enabled). +`compiler_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `compiler` argument. +`compiler` | string | any valid executable name | Provides the executable name of the compiler (e.g., `gcc`, `g++`, `clang`). Must be accessible in PATH. +`pre_arguments_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `pre_arguments` argument. +`pre_arguments` | list of strings | anything | Arguments to be passed to the compiler before the source file. +`post_arguments_variables` | boolean | `true` or `false` | Indicate if variables replacement should be done in the `post_arguments` argument. +`post_arguments` | list of strings | anything | Arguments to be passed to the compiler after the source file (for example `-o` and the output path). +`output_file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `output_file` argument. +`output_file` | string | any valid path | A path relative to `root_folder` that indicate to VyBuild which file to put into cache or to extract from cache. The parent folder must already exists. **Must be empty** if using path completion. +`success_status` | list of integers | any integers | Indicate the integers that should be considered as a success of the command. If the output code of the command isn't in this list, the command is considered as failed. +`ignore_success_status` | boolean | `true` or `false` | If this field is `true`, no output code will fail the action. +`cache_authorized` | boolean | `true` or `false` | Allows VyBuild to use the cache for this action. +`headers_command_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `headers_command` argument. +`headers_command` | string | shell command | A command string used to extract header dependencies. + +VyBuild features an advanced path completion system to avoid manual file listing. It is triggered when `source_files_path_completion` is `true`. + +Syntax: +- `path/to/dir/*` : VyBuild will look for all files with `path_completion_source_ext` in that specific directory. +- `path/to/dir/**` : VyBuild will recursively search for all matching files in that directory and all its subdirectories. + +When path completion is used, the `output_files` field **must be empty**. VyBuild will automatically generate the output paths by taking the source file path and replacing the source extension with the `path_completion_output_ext`. +Variables replacement is performed on the `source_files` strings before the path completion engine scans the filesystem. + +To ensure perfect cache integrity, VyBuild must know which headers are included by the source file. The `headers_command` field is executed in a shell. VyBuild automatically provides two internal variables for this command: +- `%sourcefile%`: The path to the source file being compiled +- `%dfile%`: A temporary path where VyBuild expects the dependency information to be written + +Example for GCC: +`"headers_command": "gcc -MMD -MF %dfile% -E %sourcefile% -o /dev/null"` + +For `pre_arguments` and `post_arguments`, VyBuild provides the following variable: +- `%outputfile%`: The path of the current output file (either explicitly provided in `output_files` or auto-generated via path completion). This is typically used with the `-o` flag. + +The compilation context used to generate the cache key for **each file individually** for this action includes: +- The content of the source file +- The content of all discovered header files (using `headers_command`) for this file +- The compiler binary hash and its system path +- The specific pre and post arguments (including the resolved `%outputfile%`) + +This action is natively multithreaded. VyBuild will distribute the compilation of the file set across the available CPU threads. The command of compilation for each file is executed using `execvp`. The order of execution within the set is not guaranteed, but the arguments are strictly concatenated as follows: +1. Resolved compiler path. +2. Pre-arguments (in order, local to each file). +3. Source file path (local to each file). +4. Post-arguments (in order, local to each file). + +#### `vyld_compilation` + +The `vyld_compilation` action is a high-level orchestration tool designed to produce a final VYX executable. It automates the entire pipeline: compiling C/C++ and Assembly files into temporary objects, managing a per-object cache, generating appropriate linker scripts, and performing the final link and VYX header injection. + +Syntax: +``` json + { + "action":"vyld_compilation", + "args":{ + "source_files_path_completion":..., + "source_files_variables":..., + "source_files":[ + ... + ], + "compiler_variables":..., + "compiler":..., + "source_asm_path_completion":..., + "source_asm_variables":..., + "source_asm":[ + ... + ], + "assembler_variables":..., + "assembler":..., + "linker_variables":..., + "linker":..., + "compiler_flags_variables":..., + "compiler_flags":..., + "output_file_variables":..., + "output_file":..., + "block_if_fail":..., + "object_files_cache_authorized":..., + "headers_command_variables":..., + "headers_command":..., + "payloads":[ + { + "source_file_variables":..., + "source_file":..., + "is_executable":..., + "is_writable":..., + "expected_va":... + } + ] + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|-----------------|----------------------- +`source_files_path_completion` | boolean | `true` or `false` | Enables the automatic discovery of `.c` source files using wildcards. +`source_files_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_files` list +`source_files` | list of strings | paths | List of source files or directory patterns (if path completion is enabled). +`compiler_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `compiler` argument. +`compiler` | string | any valid executable name | Provides the executable name of the compiler (e.g., `gcc`, `g++`, `clang`). Must be accessible in PATH. +`source_asm_path_completion` | boolean | `true` or `false` | Enables the automatic discovery of `.asm` source files using wildcards. +`source_asm_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_asm` list +`source_asm` | list of strings | paths | List of source assembly files or directory patterns (if path completion is enabled). +`assembler_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `assembler` argument. +`assembler` | string | any valid executable name | Provides the executable name of the assembler (e.g., `nasm`). Must be accessible in PATH and have nasm-like argument syntax. +`linker_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `linker` argument. +`linker` | string | any valid executable name | Provides the executable name of the linker (e.g., `ld`). Must be accessible in PATH and be compatible with `ld` linker script. +`compiler_flags_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `compiler_flags` argument. +`compiler_flags` | string | any valid compiler arguments | Custom flags passed to the C compiler during the object generation phase. +`output_file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `output_file` argument. +`output_file` | string | any valid path | A path relative to `root_folder` that indicate where to put the produced VYX executable. The parent folder must already exists. +`block_if_fail` | boolean | `true` or `false` |If `true`, any error in the pipeline stops the entire action +`object_files_cache_authorized` | boolean | `true` or `false` | Enables caching at the individual object file level (not the final binary). +`headers_command_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `headers_command` argument. +`headers_command` | string | shell command | A command string used to extract header dependencies. + +Each entry in the `payloads` list defines an external resource to be embedded in the VYX file: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`source_file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_file` string. +`source_file` | string | any valid path | Path to the raw data file to be integrated. +`is_executable` | boolean | `true` or `false` | Sets the executable flag in the VYX payload header. +`is_writable` | boolean | `true` or `false` | Sets the writable flag in the VYX payload header. +`expected_va` | string | string formatted as `0xNNNNNNNNNNNNNNNN` where each `N` must be a valid hexadecimal number | The specific virtual address where this payload must be mapped. + +When `vyld_compilation` is triggered, VyBuild call to its Vyld integration, which follows a rigorous multi-stage process to ensure the resulting binary strictly adheres to the VYX specifications: + +**1. Object Compilation Phase** + +VyBuild first processes all C/C++ source files with multithreading. Each file is compiled into a temporary object file. If caching is enabled, Vyld uses the VyBuild cache to checks for each individual object. The cache key includes the source content, discovered headers, compiler hash, and flags. Object files are stored in a managed temporary directory and are not exposed to the user after the build. + +**2. Assembly Phase** + +All assembly files are then processed. Unlike C compilation, this phase is currently single-threaded. The assembler is invoked with NASM-compatible arguments to produce the remaining object files. + +**3. Automated Linker Script Generation** + +Instead of requiring a manual linker script, `vyld_compilation` dynamically generates a script tailored for the VYX format. It enforces: + +- The specific section order: `.text` -> `.data` -> `.rodata` -> `.bss` +- Memory alignment on 4 kilobytes boundaries (0x1000) +- Correct mapping of the base addresses generated in the build pipeline + +**4. Final Linking & VYX Wrapping** + +The linker is called using the generated script to produce a temporary ELF binary. VyBuild then: +- Extracts the raw binary data for each section +- Calculates the required padding to ensure each section starts on a new page +- Header Injection: Constructs the VYX header +- Payload Integration: Appends each specified payload at the end of the file, preceded by the payload header + +To ensure perfect cache integrity, VyBuild must know which headers are included by the source file. The `headers_command` field is executed in a shell. VyBuild automatically provides two internal variables for this command: +- `%sourcefile%`: The path to the source file being compiled +- `%dfile%`: A temporary path where VyBuild expects the dependency information to be written + +Example for GCC: +`"headers_command": "gcc -MMD -MF %dfile% -E %sourcefile% -o /dev/null"` + +### Filesystem related actions + +All filesystem related actions are allowed in multithreaded parts of the build pipeline. However, its the responsability of the user to ensure that the effect of a filesystem action in a multithreaded part of the pipeline doesn't collide with another action. +Please keep in mind that not all filesystems manipulations are possible yet. + +#### `ensure_folder_existence` + +The `ensure_folder_existence` action will check if a folder exists. If the folder doesn't exist, it will be created. This action can create multiple folders at once. + +Syntax: +``` json + { + "action":"ensure_folder_existence", + "args":{ + "path_variables":..., + "path":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`path_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `path` string. +`path` | string | any valid path | Indicate the path of the folder to ensure the existence of. + +#### `move_file` + +The `move_file` action move a file or a folder to another folder. The destination path must be a folder and exists before the action. The original file/folder keeps its name. + +Syntax: +``` json + { + "action":"move_file", + "args":{ + "source_file_variables":..., + "source_file":"...", + "destination_folder_variables":..., + "destination_folder":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`source_file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_file` string. +`source_file` | string | any valid path | Indicate the path of the source file/folder. +`destination_folder_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `destination_folder` string. +`destination_folder` | string | any valid path | Indicate the path of the destination folder. + +**Warning:** while this action is theoretically capable of moving folders, it is not intended or designed for that. + +#### `copy_folder` + +The `copy_folder` action copy a folder into another folder. Both `source_folder` and `destination_folder` must be path to existing folders. It is a recursive copy that overwrite existing files/folders. + +Syntax: +``` json + { + "action":"copy_folder", + "args":{ + "source_folder_variables":..., + "source_folder":..., + "destination_folder_variables":..., + "destination_folder":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`source_folder_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_folder` string. +`source_folder` | string | any valid path | Indicate the path of the source folder to copy. +`destination_folder_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `destination_folder` string. +`destination_folder` | string | any valid path | Indicate the path of the destination folder. + +#### `ensure_folder_reset` + +The `ensure_folder_reset` action will check if a folder exists. If the folder doesn't exist, it will be created. If the folder exists, it will get removed (with all its content) and recreated. This action can create multiple folders at once. + +Syntax: +``` json + { + "action":"ensure_folder_reset", + "args":{ + "path_variables":..., + "path":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`path_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `path` string. +`path` | string | any valid path | Indicate the path of the folder to ensure the reset of. + +#### `copy_file` + +The `copy_file` action copy a file into a folder. `source_file` must be a path to an existing file, and `destination_folder` must be an existing folder. It will overwrite the file if a file with the same name in the destination folder already exists. + +Syntax: +``` json + { + "action":"copy_file", + "args":{ + "source_file_variables":..., + "source_file":..., + "destination_folder_variables":..., + "destination_folder":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`source_file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_file` string. +`source_file` | string | any valid path | Indicate the path of the source file to copy. +`destination_folder_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `destination_folder` string. +`destination_folder` | string | any valid path | Indicate the path of the destination folder. + +### Cache related actions + +The cache being thread-safe, these two actions can be used safely in multithreaded part of any build pipelines. + +#### `extract_from_cache` + +The `extract_from_cache` action will extract a file from the cache based on the provided key. If a file already exists at the path indicated by `output_file`, it will overwrite it. If the cache doesn't contain anything associated to that key, the action fails silently without stopping the build pipeline. + +Syntax: +``` json + { + "action":"extract_from_cache", + "args":{ + "target_variables":..., + "target":..., + "output_file_variables":..., + "output_file":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`target_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `target` string. +`target` | string | anything | Indicate the key to use to retrieve the cached object. +`output_file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `output_file` string. +`output_file` | string | any valid path | Indicate the path of the destination file. + +#### `store_in_cache` + +The `store_in_cache` action store a file in cache. If the cache already contains the provided key, the `overwrite_allowed` argument will specify if the cache object is overwritten or not. If `overwrite_allowed` is `false` and the cache already contains the key, the action will fail silently. + +Syntax: +``` json + { + "action":"store_in_cache", + "args":{ + "key_variables":..., + "key":..., + "file_variables":..., + "file":..., + "overwrite_allowed":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`key_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `key` string. +`key` | string | anything | Indicate the key to use to store the file. +`file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `file` string. +`file` | string | any valid path | Indicate the path of the file to store in cache. +`overwrite_allowed` | boolean | `true` or `false` | Indicates if the overwrite of already-existing cache object is allowed. + +### Control flow related actions + +VyBuild provides a way to build dynamic build pipelines using control flow actions. These actions are the following: +- `run_actions_if`: contains two arguments, `condition` and `actions`. `actions` is a list of actions to execute if the evaluated condition is satisfied. +- `run_actions_if_else`: contains three arguments, `condition`, `actions_if` and `actions_else`. `actions_if` is a list of actions executed if the condition is satisfied. Otherwise, `actions_else` is a list of actions executed if the condition isn't satisfied. +- `run_submodule_if`: this action is the same as `run_submodule`, except it contains a condition object that will determine if the submodule is executed or not, based on the satisfaction of the condition. + +These two actions enforce the rules on multithreading usage depending on where they are executed. + +#### Conditions + +Conditions are a special kind of JSON objects in VyBuild. They have the following syntax: +``` json + "condition":{ + "condition_variables":..., + "condition":..., + "condition_args_variables":..., + "condition_args":[ + ... + ] + } +``` + +`condition_variables` and `condition_args_variables` are booleans specifying if the variables replacement process should be performed on their respective fields. `condition` is a string and `condition_args` is a list of strings. + +Here are described the available conditions with their arguments and behaviour: + +Name | Arguments | Behaviour +-----|-----------|---------- +`folder_exists` | Expect one argument: the path of the folder | Returns `true` if the folder exists +`folder_not_exists` | Expect one argument: the path of the folder | Returns `true` if the folder doesn't exist +`folder_empty` | Expect one argument: the path of the folder | Returns `true` if the folder is empty +`folder_not_empty` | Expect one argument: the path of the folder | Returns `true` if the folder isn't empty +`cache_contains` | Expect one argument: the key of the cache object | Returns `true` if the cache contains an object associated with that key +`cache_not_contains` | Expect one argument: the key of the cache object | Returns `true` if the cache doesn't contain an object associated with that key +`var_exists` | Expect one argument: the name of the variable | Returns `true` if the variable exists +`var_not_exists` | Expect one argument: the name of the variable | Returns `true` if the variable doesn't exist +`var_equals` | Expect two arguments in order: the name of the variable and the value | Returns `true` if the variable is equal to the value. Stop the build pipeline if variable doesn't exist +`var_not_equals` | Expect two arguments in order: the name of the variable and the value | Returns `true` if the variable isn't equal to the value. Stop the build pipeline if variable doesn't exist. + +#### `exit_current_module` + +The `exit_current_module` action is a special action that can only be executed in a list of actions from a `run_actions_if` or `run_actions_if_else` action. It exits the current module, and stop the build pipeline if the current module is the root module. + +Syntax: +``` json + { + "action":"exit_current_module", + "args":{ + "is_fail":... + } + } +``` + +The `is_fail` argument allows to completely stop the build pipeline even if the current module isn't the root module. + +### Multithreading related actions + +VyBuild provides a clear way to track how the build pipeline is parallelized: you control exactly how you want your pipeline to be parallelized. + +#### `run_submodule` + +The `run_submodule` action allows you to load and run another module as a submodule. The module can be executed on the main thread of VyBuild (blocking the build pipeline until it completes) or as another process (using `fork`). If `block_if_fail` is `true` and the submodule is executed in another process, VyBuild will only stop the build pipeline if the fork failed, not if the execution of the submodule fail. The pipeline continue on the main process and the submodule process continue until the submodule execution end, without any synchronization between the two processes once the fork succeded. If `block_if_fail` is `true` and the submodule is executed in the main process, VyBuild will stop the build pipeline immediatly. If `block_if_fail` is `false`, the build pipeline will continue no matter the returned status of the submodule execution. + +Syntax: +``` json + { + "action":"run_submodule", + "args":{ + "file_variables":..., + "file":..., + "wait":..., + "block_if_fail":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `file` string. +`file` | string | any valid path | Indicate the path of the submodule to execute. If the path is relative, tt must be accessible from the root folder of the current module. +`wait` | boolean | `true` or `false` | If `false`, the submodule is executed in another process. If `true`, the submodule is executed on the main process. +`block_if_fail` | boolean | `true` or `false` | If `true`, any error in the submodule (except others errors than fork failure if `wait` is `false`) will stop the build pipeline. + +#### `run_actions_parallel` + +The `run_actions_parallel` action allow for multithreaded actions execution without loading another module. All actions are placed in a queue and a certain amount of threads determined by this formula `min(number_of_actions,number_of_physical_threads)` is created. This action doesn't offer any synchronization or order of execution guarantee. It just block the main pipeline until all parallel actions are finish. However, if any action executed in a thread return anything other than a success, the entire build pipeline is stopped, including others threads. + +The following actions can't be run in parallel by `run_actions_parallel`: `run_submodule`, `run_actions_parallel`, `vyld_compilation`, `run_submodule_if`, `run_submodule_parallel`, `compile_multiple_cpp`. + +Syntax: +``` json + { + "action":"run_actions_parallel", + "args":{ + "actions":[ + ... + ] + } + } +``` + +This action only has one argument: the list of actions to run in parallel. + +#### `run_submodule_parallel` + +The `run_submodule_parallel` action allows for multithreaded submodules execution. All submodules are placed in a queue and a certain amount of threads determined by this formula `min(number_of_submodules,number_of_physical_threads)` is created. This action doesn't offer any synchronization or order of execution guarantee. It just blocks the main pipeline until all parallel submodules are finish. However, if any submodule executed in a thread return anything other than a success, the entire build pipeline is stopped, including others threads. + +The `run_submodule_parallel` enforces a ban on actions that could start an uncontrolled thread creation chain. That mean that any submodule ran using this action will fail (and stop the build pipeline) as soon as it encounters one of the following action: `run_submodule`, `run_actions_parallel`, `vyld_compilation`, `run_submodule_if`, `run_submodule_parallel`, `compile_multiple_cpp`. + +Each thread has its own working directory changed to the root folder of the submodule it executes. + +Syntax: +``` json + { + "action":"run_submodule_parallel", + "args":{ + "submodules_variables":..., + "submodules":[ + ... + ] + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`submodules_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `submodules` list of strings. +`submodules` | list of strings | any valid path | Indicate the path of the submodule to execute. If the path is relative, it must be accessible from the root folder of the current module. + +### FAT32 related actions + +VyBuild integrates its own FAT32 generator, that can be extremely helpful for projects that needs to generate FAT32 images, especially if you are building your own disk image. Because VyBuild is still in early development, it can only generate FAT32 images with these limitations: +- No boot code compatibility (it will be set to 0) +- Custom enforced OEM name and volume label +- No FAT12 or FAT16 generation +- 512 bytes per sector, 1 sector per cluster, 32 reserved sectors count, 2 FATs +- Limited to short files names, lowercases letter are automatically transformed to uppercases letters +- Directory are only allocated one cluster and can't be extended/expanded later, that mean that a directory can't contain more than 14 files or subfolder. Technically, it's 16 but we automatically add the `.` and `..` entries. This is a limitation we planned to raise in the future +- Empty files in the image need to be created from an existing empty file on the disk +- Once a folder has been created or a file has been flashed, it can no longer be edited, copied, moved, expanded or deleted. But that also implies that files are always contiguous on the FAT32 images +- Each folder in a path must be created one by one +- FSInfo structure aren't completed with actuals useful information + +This implementation doesn't have the objective of being a complete FAT32 driver but rather, a simpler alternative to easily generate FAT32 image directly in the build pipeline, avoiding the complex Linux tricks and need for root permissions usages. But, it's still sufficient for generating simple ESP partition. + +**Warning:** while there is no global lock on the FAT32 image generator/on each FAT32 image, there is also no ban of FAT32 related actions in multithreaded part of the build pipeline. This mean that the user is fully responsible that no more than one part of the build pipeline use the FAT32 image generator at the same time. + +#### `create_fat32` + +The `create_fat32` action will create an empty FAT32 image in RAM and will initialize all FAT32 structures. The value in `key` is used to identify the image for later actions on this image. The size must be provided in bytes and must be a multiple of 512. The key must not be empty. + +Syntax: +``` json + { + "action":"create_fat32", + "args":{ + "key_variables":..., + "key":..., + "size":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`key_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `key` string. +`key` | string | anything except empty string | Indicate an identifier for the FAT32 image. +`size` | integer | any integer multiple of 512 except 0 | Indicate the size in bytes of the FAT32 image. It should be at least 32MB to be recognized as a valid FAT32. + +#### `create_folder_fat32` + +The `create_folder_fat32` action will create a folder at the indicated path inside the FAT32 image referenced by the provided key. The path must start with `/`, indicating the root folder of the FAT32 image. All of the folder names in the path should be in uppercases letters and not longer than 8 characters. The last folder name is the name of the folder to create. The rest of the path must already exist inside the FAT32 image. + +Example: `/EFI/BOOT`: Here `BOOT` is the name of the folder to create and `EFI` must already exist as a folder inside the root folder. + +Syntax: +``` json + { + "action":"create_folder_fat32", + "args":{ + "key_variables":..., + "key":..., + "full_path_variables":..., + "full_path":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`key_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `key` string. +`key` | string | anything except empty string | Indicate an identifier for the FAT32 image. +`full_path_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `full_path` string. +`full_path` | string | any valid path in the FAT32 image | Indicate the full path of the folder to create. + +#### `create_file_fat32` + +The `create_file_fat32` action will create a file at the indicated path inside the FAT32 image referenced by the provided key. All the folders in the full path must already exist. The last name in the full path is interpreted as the file name and must satisfies the 8.3 file name format (if file name isn't formated as expected, VyBuild will fail the action and therefore the build pipeline). The content of the file is read from a file on disk and the file size is automatically determined by the file size of the source file on disk. Source file must be an existing regular file. + +Syntax: +``` json + { + "action":"create_file_fat32", + "args":{ + "key_variables":..., + "key":..., + "source_path_variables":..., + "source_path":..., + "full_path_variables":..., + "full_path":..., + "is_vftm_target":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`key_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `key` string. +`key` | string | anything except empty string | Indicate an identifier for the FAT32 image. +`source_path_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_path` string. +`source_path` | string | any valid path | Indicate the path of the source file on disk. +`full_path_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `full_path` string. +`full_path` | string | any valid path in the FAT32 image | Indicate the full path of the file to create. +`is_vftm_target` | boolean | `true` or `false` | Indicate if this file is the VFTM target. If you don't know what VFTM is, set this flag to `false` and ignore it. + +#### `export_fat32` + +The `export_fat32` action exports the FAT32 image referenced by the provided key to a specified file on the disk. `disk_guid_var` and `efi_part_unique_guid_var` are two optionals arguments and must be provided only if `generate_vftm` is `true`. If you don't know what VFTM is, set the `generate_vftm` flag to `false` and ignore it. + +Syntax: +``` json + { + "action":"export_fat32", + "args":{ + "key_variables":..., + "key":..., + "export_path_variables":..., + "export_path":..., + "generate_vftm":..., + "disk_guid_var":..., + "efi_part_unique_guid_var":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`key_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `key` string. +`key` | string | anything except empty string | Indicate an identifier for the FAT32 image. +`export_path_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `export_path` string. +`export_path` | string | any valid path | Indicate the path of the file in which the FAT32 image should be exported. +`generate_vftm` | boolean | `true` or `false` | Indicates if the VFTM should be generated and integrated to the exported image. If you don't know what VFTM is, set this flag to `false` and ignore it. +`disk_guid_var` | string | any variable name without the `$` symbols | Indicate the variable that contain the disk GUID. Only mandatory if `generate_vftm` is `true`. If you don't know what VFTM is, just don't set this field. +`efi_part_unique_guid_var` | string | any variable name without the `$` symbols | Indicate the variable that contain the ESP unique GUID. Only mandatory if `generate_vftm` is `true`. If you don't know what VFTM is, just don't set this field. + +### Disk related actions + +VyBuild integrates its own disk images generator. Because VyBuild is still in early development, it can only generate disk images with these limitations: +- No MBR support at all +- 128 partition entries maximum +- 128 bytes per partition entries +- GUID must be provided as UUID v4 syntax. All 16 bytes of data are considered given as Big Endian, and so the first 8 bytes of data will be converted to Little Endian to comply with the GPT specification +- Fixed LBA size of 512 bytes +- No partition alignment other than LBA size + +This implementation doesn't have the objective of being a complete disk driver but rather, a simpler alternative to easily generate disk image directly in the build pipeline, avoiding the complex Linux tricks and need for root permissions usages. But, it's still sufficient for generating simple disk images, even with custom partitions. + +**Warning:** while there is no global lock on the disk image generator/on each disk image, there is also no ban of disk related actions in multithreaded part of the build pipeline. This mean that the user is fully responsible that no more than one part of the build pipeline use the disk image generator at the same time. + +#### `create_disk` + +The `create_disk` action will create an empty disk image in RAM and will initialize all GPT structures. The value in `key` is used to identify the disk image for later actions on this image. The size must be provided in bytes and must be a multiple of 512. The key and disk GUID must not be empty. + +Syntax: +``` json + { + "action":"create_disk", + "args":{ + "key_variables":..., + "key":..., + "size":..., + "disk_guid_variables":..., + "disk_guid":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`key_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `key` string. +`key` | string | anything except empty string | Indicate an identifier for the disk image. +`size` | integer | any integer multiple of 512 except 0 | Indicate the size in bytes of the disk image. +`disk_guid_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `disk_guid` string. +`disk_guid` | string | any valid UUID v4 | Indicate a GUID for the disk under the form of a UUID v4 Big Endian. + +#### `add_partition_disk` + +The `add_partition_disk` action will create a new partition on the disk image referenced by the provided key. The key must be a valid disk image key. The type GUID, unique GUID and name must not be empty. The source file path must lead to a valid partition image stored in an existing regular file on disk. + +Syntax: +``` json + { + "action":"add_partition_disk", + "args":{ + "key_variables":..., + "key":..., + "type_guid_variables":..., + "type_guid":..., + "unique_guid_variables":..., + "unique_guid":..., + "name_variables":..., + "name":..., + "source_file_variables":..., + "source_file":... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`key_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `key` string. +`key` | string | anything except empty string | Indicate an identifier for the disk image. +`type_guid_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `type_guid` string. +`type_guid` | string | any valid UUID v4 | Indicate a type GUID for the partition under the form of a UUID v4 Big Endian. +`unique_guid_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `unique_guid` string. +`unique_guid` | string | any valid UUID v4 | Indicate a unique GUID for the partition under the form of a UUID v4 Big Endian. +`name_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `name` string. +`name` | string | anything except empty string | Indicate a name for the partition. It's recommanded only putting ASCII characters in this field, as VyBuild will convert in a very simple manner into UTF-16LE: simply casting each `char` into `uint16_t` +`source_file_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `source_file` string. +`source_file` | string | any valid path | Indicate the path of the partition image on disk. + +#### `export_disk` + +The `export_disk` action exports the disk image referenced by the provided key to a specified file on the disk. + +Syntax: +``` json + { + "action":"export_disk", + "args":{ + "key_variables":..., + "key":..., + "export_path_variables":..., + "export_path":"... + } + } +``` + +Arguments: + +Name | Type | Possible values | Role +-----|------|------------------|----- +`key_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `key` string. +`key` | string | anything except empty string | Indicate an identifier for the disk image. +`export_path_variables` | boolean | `true` or `false` | Indicates if variables replacement should be performed in the `export_path` string. +`export_path` | string | any valid path | Indicate the path of the file in which the disk image should be exported. diff --git a/docs/vybuild/cache.md b/docs/vybuild/cache.md new file mode 100644 index 0000000..4e10790 --- /dev/null +++ b/docs/vybuild/cache.md @@ -0,0 +1,14 @@ +# Cache + +## Introduction + +VyBuild integrate its own cache, stored in the `.vybuild_cache` folder in the root of the project folder, identified using `getcwd` at the start of the build pipeline execution. It is recommanded to put this folder in your `.gitignore` file if you use Git, or any other equivalent source control software. + +## Smart cache + +To ensure that the cache only contains what is actually needed for efficient compilation without taking too much storage, VyBuild integrate a unique technology called smart cache. The smart cache is enabled by default and ensure that the cache remain reasonably small on disk. + +Instead of relying on metadata like file dates or complex dependency graphs, the smart cache acts at the root of the root of the cache subsystem, and it works even on custom build artifacts stored in cache by the user. It is built upon three simple rules: +- any new cache object that has been created during this build pipeline execution remains in cache +- any cache object that was already in the cache before this build pipeline execution, and that have been used/extracted from the cache during this build pipeline execution remains in cache +- any cache object that was already in the cache before this build pipeline execution, and that hasn't been used/extracted from the cache during this build pipeline execution will be deleted at the end of this build pipeline execution diff --git a/docs/vybuild/index.md b/docs/vybuild/index.md new file mode 100644 index 0000000..fa05eca --- /dev/null +++ b/docs/vybuild/index.md @@ -0,0 +1,30 @@ +# VyBuild Docs + +## Introduction + +VyBuild is Vystem build system. It has been designed to considerably reduce the need for external tools and the pain of writing custom scripts. It is opinionated and optimized for OS development. While it was designed for Vystem, it can be used for others OS project, but feature such as Vyx/Vyld usage and VFTM aren't guaranteed to work. VyBuild is very integrated into the Vystem ecosystem and should not be considered complete for now. + +## Features + +VyBuild is capable of the following: +- Compiling C, C++ and Assembly file, with custom arguments, compiler, assembler, and even linker in certain cases. +- Automatically caching build artifacts and compilation objects files, with cached objects invalidation down to modification in the compiler/assembler binary and in C/CPP files included headers +- Automatically purging the cache to keep only newly created objects and objects of previous build that have been used during a build, preventing garbage accumulation +- Letting the user uses the cache how they want to store custom objects +- Running command in indicated folder, running command with auto-faillure if command return a certain status code, show output of commands live, on failure or never, save command output to provided file +- Giving the user complete control over how the build pipeline is parralelised, with flexible options at compilation, actions or modules granularity level +- Compiling Vyx executable with an upgraded and more powerful integration of Vyld +- Acting on the filesystem, like moving/copying files/folder, ensure folder existence or reset +- Letting the user uses system variables (like `%rootcallerfolder%`) or define their own to use in almost any actions field, as well as providing variable on command line argument of VyBuild +- Running differents actions or modules depending on differents condition, like folder existence, cache presence or variable value/existence +- Create fully valid FAT32 images (only support short file names) and fully valid disk images with GPT tables, custom type/unique partitions GUID and importing partitions from file +- Integrating Vystem FAT Trusted Manifest support for FAT32 images generation and interaction with `keygen` + +## Index + +This documentation is intended to be read in the following order: +1) [Modules](modules.md) +2) [Actions](actions.md) +3) [Variables](variables.md) +4) [Cache](cache.md) +5) [Usage](usage.md) diff --git a/docs/vybuild/modules.md b/docs/vybuild/modules.md new file mode 100644 index 0000000..1e37bf9 --- /dev/null +++ b/docs/vybuild/modules.md @@ -0,0 +1,46 @@ +# Modules + +## Introduction + +Modules are the backbone of VyBuild. They allow you to precisely describe the build process of your project. They are JSON files with a very strict but clear syntax. + +## Syntax + +Modules can be executed as root module (called from command line) or submodule (called from another module). +A module is made of several fields indexed in a dictionnary. Here is an example: + +``` json +{ + "version":"0.1", + "root_folder":"...", + "run_context":"...", + "name":"...", + "global_uuid":[ + ... + ], + "global_vars":{ + ... + }, + "actions":[ + ... + ] +} +``` + +### Mandatory fields + +Each module has 5 mandatory fields: +- `version`: a string indicating the version of VyBuild JSON syntax. It must be set to the current version of the VyBuild JSON syntax, which is currently `0.1` +- `root_folder`: a string indicating the working folder of this module, all relative paths must be accessible in this folder. You can use variables in this field (see [variables docs](variables.md)). The path indicated in this field should always be absolute for maximum reliability +- `run_context`: a string indicating in which context this module can be executed. Possible values are: + - `both`: the module can be executed as root module and submodule + - `root`: the module can only be executed as root module + - `sub`: the module can only be executed as submodule +- `name`: a string indicating the name that will be displayed in VyBuild call tree +- `actions`: a list of actions (see [actions docs](actions.md)) to execute in the module + +### Optional fields for root module + +Modules called from the command line can include the following optional fields : +- `global_uuid`: a list of string giving variables names that will be filled with random UUIDs v4 as each build. They can be used as regular variables +- `global_vars`: a dictionnary of string to string entries, associating variables names to their contents. For more informations, see [variables docs](variables.md) diff --git a/docs/vybuild/usage.md b/docs/vybuild/usage.md new file mode 100644 index 0000000..0585375 --- /dev/null +++ b/docs/vybuild/usage.md @@ -0,0 +1,35 @@ +# Usage + +## Build + +In order to use VyBuild, you must compile it first. For this, use the `build.sh` script located in the `vybuild` folder. This script should only be used from the root folder of the Vystem project, just like this: + +``` bash +vybuild/build.sh +``` + +The `vybuild` binary will be compiled inside the folder of same name. + +## Usage + +VyBuild can be used like this: + +``` bash +vybuild/vybuild +``` + +The first argument must be the path to the root module. Arguments that comes after that will be sorted into two categories: +- VyBuild arguments: if VyBuild recognize an argument specific to the build system, it will remove it from the exposed arguments +- Build arguments: these arguments will be exposed to the build pipeline using system variables + +Here is the list of VyBuild arguments to this day: +- `--purge-cache`: purge the cache before starting the build pipeline +- `--disable-smart-cache`: disable the smart cache feature for this execution of the build pipeline + +## Licenses + +External libraries used inside VyBuild: +- ELFIO, made by Serge Lamikhov-Center, sourced from [serge1/ELFIO](https://github.com/serge1/ELFIO), under the MIT license +- json, made by Niels Lohmann, sourced from [nlohmann/json](https://github.com/nlohmann/json), under the MIT license + +Others libraries are used when loading the dynamic library `commoncrypto`, which can be found [here](../boottools/commoncrypto.md) diff --git a/docs/vybuild/variables.md b/docs/vybuild/variables.md new file mode 100644 index 0000000..521a459 --- /dev/null +++ b/docs/vybuild/variables.md @@ -0,0 +1,59 @@ +# Variables + +## Introduction + +Variables in VyBuild allow for rapid changes of the build pipeline parameters and can be used almost anywhere. + +## Overview + +In VyBuild, there are two types of variables: +- user-defined variables (also called global variables): these are defined as pairs of string in the `global_vars` field of every root module. They are usables in all parts of the build pipeline without restriction. +- systems variables: these are special variables defined by VyBuild containing specific values. Some are usable globally and some are only usables in some fields. For more information about these ones, see [actions docs](actions.md) + +## Using a global variable + +To define a global variable with a custom value, simply add a pair of string inside the `global_vars` field of the root module of your pipeline. + +To define a global variable with an automated UUID v4 that changes at each build, simply add a string inside the `global_uuid` field of the root module of your pipeline. + +You can use variables in almost every fields that are either a string or a list of strings. You know if a field support variables if there is a boolean field in the same action with the name `_variables`. These variables fields are mandatory and indicate if VyBuild will attempt to detect and replace variables in any field where the corresponding variable field is set to `true`. + +To use global variables in a field that support it, just put your variable name between `$`. + +Example with `SOME_VARIABLE` containing `somes informations`: +``` json +{ + "field_variables":true, + "field":"hey$SOME_VARIABLE$hey" +} +``` + +In this example, the value that VyBuild sees after replacing the variable is `heysomes informationshey`. + +Variable names are usually in uppercases letters to avoid any confusion with others parts of a field. This is to follow the same C macros style. + +### Specials global variables + +Some global variables are a way for some parts of VyBuild to let the user add features to them. Here is a exhaustive list of these special global variables +- `__VYBUILD_COMPILER_HASH_`: any global variables starting with this prefix will be used by actions that compile C/CPP code to include optional information on the used toolchain. These actions will consider the content of these variables as already-formated commands that they can execute and include the output of these commands into the cache keys of each cached objects. That way, any change to the toolchain can be detected and trigger a recompilation + +## Using systems variables + +Systems variables are variables created by VyBuild, usable in certain contexts. This file will only cover systems variables that aren't specific to certains actions. + +Systems variables can be used in almost any fields with some limitations. When used, they are framed with `%`. Here is a complete list: + +Name | Content | Behaviour +-----|---------|---------- +`%rootcallerfolder%` | The full path of the parent folder of the root module of every build pipeline | Usable in every action fields that support it. Can also be used in the `root_folder` field of every module but alone (can't be combined in a path for this field). +`%filefolder%` | The absolute path of the directory containing the current module's JSON file | Can only be used alone (can't be combined in a path for this field) in the `root_folder` of every module. + +Command line arguments that aren't VyBuild parameters will be exposed as systems variables under the index of the argument in the command line. + +Example: + +``` bash +vybuild img +``` + +In this example, the system variable `1` will be created by VyBuild with the value `img`, and can be used in any action fields that support variables using the syntax `%1%`. diff --git a/docs/vyld/index.md b/docs/vyld/index.md deleted file mode 100644 index b2c08e6..0000000 --- a/docs/vyld/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# Vyld Docs - -Vyld, standing for Vystem Linker, is a specialised linker designed to convert ELF binaries to the VYX executable format. This documentation is divided into two parts: -- [The VYX executable format](vyx.md) -- [The Vyld utility](vyld.md) diff --git a/docs/vyld/vyld.md b/docs/vyld/vyld.md deleted file mode 100644 index 571d0bf..0000000 --- a/docs/vyld/vyld.md +++ /dev/null @@ -1,67 +0,0 @@ -# Vyld Docs - -## Introduction - -Vyld, standing for Vystem Linker, is the utility responsible for creating VYX executable from ELF binaries. Vyld has been intended to be used only on a regular Linux system. For a better understanding, it's recommanded you read the [VYX format docs](vyx.md) first. - -## Detailled informations - -Folder: `vyld` -Source code file: `vyld.cpp` - -For building the `vyld` utility, use the following command: -``` bash -g++ vyld.cpp -o vyld -``` - -External library: -- ELFIO, made by Serge Lamikhov-Center, sourced from [serge1/ELFIO](https://github.com/serge1/ELFIO), under the MIT license - -## Usage - -Requirement: having the `gcc` compiler and `ld` linker reachable in path. For the moment, only the `gcc` compiler is supported. - -The `vyld` utility can be used like this: -``` bash -vyld ... -``` - -Each path provided except the last one has to be C file, or else the compilation might fail. The last path can be any extension, but for standard respect, it should be a VYX file. - -Vyld can accept custom compilation flags for provided C files if they are passed by using the `VYLD_COMPILATION_FLAGS` environnement variable. They are added to the mandatory compilation flags for provided C files but they will not replace them. The mandatory compilation flags for provided C files are: -``` bash --fno-pic -m64 -mcmodel=large -``` - -The mandatory compilation flag for the `_vyx_start.c` entry point are: -``` bash --ffreestanding -nostdlib -nostartfiles -Wall -Wextra -fno-stack-protector -fno-builtin -fno-pic -m64 -mcmodel=large -``` -These flags aren't applied to provided C files unless passed inside `VYLD_COMPILATION_FLAGS`. - -Vyld need to have access to the `_vyx_start.c` file in his executable directory in order to compile any VYX binary. This file is the entry point of any VYX executable. - -Command example: -``` bash -vyld hello.c io.c binary.vyx -VYLD_COMPILATION_FLAGS="-Wall -Wextra -Werror -Wpedantic" vyld hello.c io.c binary.vyx -``` - -We plane to expand drastically the capabilities and versatility of the `vyld` utility and the VYX format in the future, but for the moment, it's sufficient for what we need (loading the Shelter kernel). - -## Detailled generation processus - -1) Obtaining his own executable path by reading `/proc/self/exe` in order to obtain a deterministic working directory -2) Searching for flags provided into the `VYLD_COMPILATION_FLAGS` -3) Checking for existence of `_vyx_start.c ` and compiling it into `_vyx_start.o` using mandatory compilation flags for entry point. The resulting object file is stored inside the `vyld` executable directory -4) Iterating for each provided C files: finding his location and generating his output name under the format `.o` -5) Iterating for each provided C files: compiling each C file into an object file using mandatory compilation flags for provided C files and flags passed through `VYLD_COMPILATION_FLAGS`. The resulting objects files are stored inside the `vyld` executable directory -6) Combining all objects files (entry point and all provided files under their object form) into one object file named `combined.o` and stored inside the `vyld` executable directory. For that, we use the `gcc -r` feature of `gcc`. The entry point object file is specifically added in first position -7) Opening `combined.o` and obtaining sections size for `.text`, `.data`, `.rodata` and assimiled sections as well as `.bss` section. Padding these sizes to the nearest multiple of 4096 bytes superior to these sizes -8) Generating the `.text` section base virtual address (VA) and stack base VA, aligned on 4096 bytes pages -9) Generating a custom linker script to correctly link the `combined.o` file with the right VAs inside the code and putting in order all the sections into the final binary -10) Linking the `combined.o` file into an ELF executable named `compiled.elf` and stored inside the `vyld` executable folder -11) Opening the `compiled.elf` binary, extracting all sections, generating VYX header and executable - -The range for generating `.text` section base is currently `0xFFFF800000000000` to `0xFFFF900000000000-1`, then padded to the nearest page boundary. -The range for generating stack base is currently `0xFFFFF00000000000` to `0xFFFFFF8000000000-0x100000`, then padded to the nearest page boundary. diff --git a/docs/vyld/vyx.md b/docs/vyx.md similarity index 58% rename from docs/vyld/vyx.md rename to docs/vyx.md index b071224..10477e0 100644 --- a/docs/vyld/vyx.md +++ b/docs/vyx.md @@ -6,15 +6,16 @@ The VYX format, standing for Vystem Executable, is a very simple binary format m ## Header -Because VYX format has been designed to provide a simple way to load any kind of binary, we wanted to make it as easely updatable as possible. For the moment, it's just a very simple format built for loading the Shelter kernel, but in a few updates, it will be use for loading all kind of binaries. No spoiler on that. The header is designed like that: +Because VYX format has been designed to provide a simple way to load any kind of binary, we wanted to make it as easily updatable as possible. For the moment, it's just a very simple format built for loading the Shelter kernel, but in a few updates, it will be use for loading all kind of binaries. No spoiler on that. The header is designed like that: - Signature: three bytes spelling `VyX` in ASCII -- VYX format version: the version of the VYX format used in the binary, represented as an uint16_t. Depending on the version number, the following structure will probably changed a lot. The current version is `0x0001`. +- VYX format version: the version of the VYX format used in the binary, represented as an uint16_t. Depending on the version number, the following structure will probably changed a lot. The current version is `0x0002`. - `.text` base address: the virtual address (VA) at which the `.text` should be loaded. It should be aligned on the boundary of a 4 kilobytes page. Represented as an uint64_t -- stack base: the VA at which the stack base should be setuped. Be careful, it indicate the base, not the top. It should be aligned on the boundary of a 4 kilobytes page. Represented as an uint64_t +- stack base: the VA at which the stack base should be setup. Be careful, it indicates the base, not the top. It should be aligned on the boundary of a 4 kilobytes page. Represented as an uint64_t - the size of the `.text` section: It should be aligned on a multiple of 4096 bytes. Represented as an uint64_t - the size of the `.data` section: It should be aligned on a multiple of 4096 bytes. Represented as an uint64_t - the size of the `.rodata` section: It should be aligned on a multiple of 4096 bytes. Represented as an uint64_t - the size of the `.bss` section: It should be aligned on a multiple of 4096 bytes. Represented as an uint64_t +- the number of payloads integrated into the VYX file. Represented as an uint64_t All the multibytes integers should be written in little endian. The VYX executable format has been made for x86-64 only binary. @@ -23,9 +24,26 @@ All the multibytes integers should be written in little endian. The VYX executab The VYX format only support three sections inside the binary that should be in the following order: `.text`, `.data`, `.rodata`. The `.bss` should be initialized and zeroed by the loader just after the `.rodata` section. The space occupied by the three sections inside the binary should occupy a multiple of 4096 bytes, according to the size indicated in the header, padded with zeroes if necessary. For example, if each sections take 2 pages, after being padded to the nearest multiple of 4096 bytes superior to their real size, and that the `.text` base is 0x1000, `.text` should be located at 0x1000, `.data` at 0x3000, `.rodata` at 0x5000 and `.bss` at 0x7000 +## Payloads + +The VYX format now support, as of `0x0002` version, the integration of payloads. There are additionnal ressources that the VYX loader need to discover. + +This discovery process is started from the end of the `.rodata` section. The loader need to look for the signature `VPAYLOAD` in ASCII. Once localised, the loader know it has found a payload header, which is structured like this: +- Signature: 8 bytes +- Payload size in bytes: represented as an uint32_t +- Payload size in amount of 4 kilobytes pages: represented as an uint32_t +- Payload mapping flags: 1 byte specifying how the VYX loader should map the payload in the virtual address space of the program being loaded: + - Bit 0: if 1, the payload should be mapped as executable data + - Bit 1: if 1, the payload should be mapped as writable data +- Payload virtual address! the address at which the payload should be mapped by the VYX loader. Should be aligned on 4 kilobytes pages frontier and shouldn't be in reserved virtual address space for program image and stack + +Then, for the indicated payload size in bytes, the VYX loader should extract the payload (that come immediately after the payload header) and map it accordingly. Restriction can be applied on mapping flags depending on the VYX loader context. + +If the payload size in bytes is bigger that the remaining size in bytes into the VYX file, it indicates VYX file corruption. The discovery process continue as long as the amount of payloads discovered isn't the same as indicated into the header. + ## Specifications -The VYX binaries use the SystemV ABI. They doesn't support rellocations nor dynamic linking. While relative addressing into the binary code is theorically working, all the Vystem binaries will be compiled 64 bits static addressing with position-dependent code (non-PIC), especially the kernel. That why respecting the indicated `.text` section base and order of sections loading is extremely important. +The VYX binaries use the SystemV ABI. They doesn't support rellocations nor dynamic linking. While relative addressing into the binary code is theoretically working, all the Vystem binaries will be compiled 64 bits static addressing with position-dependent code (non-PIC), especially the kernel. That why respecting the indicated `.text` section base and order of sections loading is extremely important. Obviously, the right privileges should be applied in term of pagging: no execution unless `.text` pages, read only `.text` and `.rodata` sections, read-write `.data` and `.bss` sections. For the moment, the entry point is located at the base of the `.text` section. The stack size can be decided at the convenience of the loader, but the stack size used for the Shelter kernel is, for the moment, 256 kilobytes. The stack growing downward, the initial stack pointer should be set to stack base + stack size. diff --git a/esp.json b/esp.json new file mode 100644 index 0000000..0f1c8e4 --- /dev/null +++ b/esp.json @@ -0,0 +1,175 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"ESP partition build", + "actions":[ + { + "action":"create_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "size":134217728 + } + }, + { + "action":"create_folder_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "full_path_variables":false, + "full_path":"/EFI" + } + }, + { + "action":"create_folder_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "full_path_variables":false, + "full_path":"/EFI/BOOT" + } + }, + { + "action":"create_folder_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "full_path_variables":false, + "full_path":"/EFI/BPSIGN" + } + }, + { + "action":"create_folder_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "full_path_variables":false, + "full_path":"/EFI/BPFILES" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_DIR$/Build/BlastproofEnv/RELEASE_GCC/X64/BlastMain.efi", + "full_path_variables":false, + "full_path":"/EFI/BOOT/BOOTX64.EFI", + "is_vftm_target":true + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/bootanim/bootanim.bin", + "full_path_variables":false, + "full_path":"/EFI/BPFILES/BOOTANIM.BIN" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/fontgen/font.fbm", + "full_path_variables":false, + "full_path":"/EFI/BPFILES/FONT.FBM" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/initfsgen/initfsfp.bin", + "full_path_variables":false, + "full_path":"/EFI/BPFILES/INITFSFP.BIN" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/initfsgen/sshash.bin", + "full_path_variables":false, + "full_path":"/EFI/BPFILES/SSHASH.BIN" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/config/bp.cfg", + "full_path_variables":false, + "full_path":"/EFI/BPFILES/BP.CFG" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/sign/bp.sig", + "full_path_variables":false, + "full_path":"/EFI/BPSIGN/BP.SIG" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/sign/font.sig", + "full_path_variables":false, + "full_path":"/EFI/BPSIGN/FONT.SIG" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/sign/initfsfp.sig", + "full_path_variables":false, + "full_path":"/EFI/BPSIGN/INITFSFP.SIG" + } + }, + { + "action":"create_file_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "source_path_variables":true, + "source_path":"%rootcallerfolder%/$EDK2_BLASTPROOF_DIR$/sign/sshash.sig", + "full_path_variables":false, + "full_path":"/EFI/BPSIGN/SSHASH.SIG" + } + }, + { + "action":"export_fat32", + "args":{ + "key_variables":false, + "key":"esp", + "export_path_variables":true, + "export_path":"%rootcallerfolder%/$EDK2_DIR$/esp.bin", + "generate_vftm":true, + "disk_guid_var":"DISK_GUID", + "efi_part_unique_guid_var":"ESP_PARTITION_UNIQUE_GUID" + } + } + ] +} diff --git a/licenses/third-party/mit_json.md b/licenses/third-party/mit_json.md new file mode 100644 index 0000000..7700166 --- /dev/null +++ b/licenses/third-party/mit_json.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2026 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/readme.md b/readme.md index fbf8f74..30d5339 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ # Vystem The Vystem project aim to designs, develops and provides a stable operating system based on the following principles: -- built completely from scratch: no code from others repositories that run in the runtime environnement (starting at kernel boot) +- built completely from scratch: no code from others repositories that run in the runtime environnement (starting at kernel boot) with exceptions made for cryptos libraries that are isolated from the kernel - with his own hybrid kernel, bootloader, userspace, all designed from scratch to fit perfectly together - using post-quantum cryptography everywhere it's pertinent to use it - with a very high emphasize on security, integrity and auditability @@ -13,7 +13,7 @@ Please note that the project has just begun and it's still in very early develop The documentation of every components already designed and implemented can be found [here](docs/index.md). -Here is somes quick links: +Here is some quick links: - [Licenses and contribute guide](docs/licenses.md) - [Build process](docs/build.md) - [Roadmap](docs/roadmap.md) diff --git a/shelter/kernel.json b/shelter/kernel.json new file mode 100644 index 0000000..6cc1a38 --- /dev/null +++ b/shelter/kernel.json @@ -0,0 +1,87 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Shelter compilation", + "actions":[ + { + "action":"compile_one_asm", + "args":{ + "source_variables":false, + "source":"lib/src/cpu/ap_boot.asm", + "assembler_variables":true, + "assembler":"$ASSEMBLER$", + "pre_arguments_variables":true, + "pre_arguments":[ + "-f $ASM_OUTPUT_FORMAT$" + ], + "post_arguments_variables":true, + "post_arguments":[ + "-o lib/src/cpu/ap_boot.bin" + ], + "output_file_variables":true, + "output_file":"lib/src/cpu/ap_boot.bin", + "success_status":[ + 0 + ], + "ignore_success_status":true, + "cache_authorized":true + } + }, + { + "action":"vyld_compilation", + "args":{ + "source_files_path_completion":true, + "source_files_variables":false, + "source_files":[ + "main.c", + "lib/src/**" + ], + "compiler_variables":true, + "compiler":"$C_COMPILER$", + "source_asm_path_completion":true, + "source_asm_variables":false, + "source_asm":[ + "lib/src/irq/**" + ], + "assembler_variables":true, + "assembler":"$ASSEMBLER$", + "linker_variables":true, + "linker":"$LINKER$", + "compiler_flags_variables":true, + "compiler_flags":"$SHELTER_COMPILATION_FLAGS$", + "output_file_variables":true, + "output_file":"$SHELTER_BINARY_NAME$", + "block_if_fail":true, + "object_files_cache_authorized":true, + "headers_command_variables":true, + "headers_command":"gcc -MMD -MF %dfile% -E %sourcefile% -o /dev/null -I%rootcallerfolder%/shelter/lib/include", + "payloads":[ + { + "source_file_variables":true, + "source_file":"%rootcallerfolder%/shelter/lib/src/cpu/ap_boot.bin", + "is_executable":false, + "is_writable":true, + "expected_va":"0x000000000000A000" + } + ] + } + }, + { + "action":"ensure_folder_existence", + "args":{ + "path_variables":true, + "path":"%rootcallerfolder%/$INITFS_DIR$" + } + }, + { + "action":"move_file", + "args":{ + "source_file_variables":true, + "source_file":"$SHELTER_BINARY_NAME$", + "destination_folder_variables":true, + "destination_folder":"%rootcallerfolder%/$INITFS_DIR$" + } + } + ] +} diff --git a/shelter/lib/include/cpu/ap.h b/shelter/lib/include/cpu/ap.h new file mode 100644 index 0000000..d31883c --- /dev/null +++ b/shelter/lib/include/cpu/ap.h @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_AP_H +#define SH_LIB_AP_H +#include "std/status.h" +#include "std/type.h" +#include "memory/memory.h" +#include "irq/gdt.h" +#include "irq/idt.h" +#include "devs/apic/lapic.h" +#define SH_AP_AP_TRAMPOLINE 0x7000 +#define SH_AP_GDT_32_PA 0x8000 +#define SH_AP_BOOTSTRAP_PA 0x9000 +#define SH_AP_TRAMPOLINE_PAYLOAD 0xA000 +#define SH_AP_STATE_PENDING 0x00 +#define SH_AP_STATE_NO_LAPIC 0x01 +#define SH_AP_STATE_OK 0x02 +// Fill the 32 bits GDT used by AP trampoline +SH_STATUS sh_ap_load_gdt_32(); +// AP boostrap structure, shared with each AP +#pragma pack(1) +typedef struct { + sh_page_PHYSICAL_ADDRESS lapic_base_pa; + sh_page_VIRTUAL_ADDRESS c_entry_point_va; + sh_page_PHYSICAL_ADDRESS page_table_pa; + sh_page_VIRTUAL_ADDRESS cpu_struct_base_area; + sh_page_VIRTUAL_ADDRESS shared_gdt_64_va; + sh_gdt_GDTR gdt_64_gdtr; + sh_idt_IDT *idt; +} sh_ap_AP_BOOTSTRAP; +#pragma pack() +// Per-CPU structure, one for each AP +#pragma pack(1) +typedef struct { + sh_uint64 cpu_id; + sh_uint32 bytes_outputed; + sh_bool timer_state; + char *temp_buffer; + sh_uint64 temp_buffer_size; +} sh_ap_PER_CPU; +#pragma pack() +// CPU structure, one for each AP +#pragma pack(1) +typedef struct { + sh_page_VIRTUAL_ADDRESS c_entry_point_stack_top_va; + sh_uint32 lapic_id; // just for the tranpoline to confirm it has found his own struct + sh_uint16 tss_selector; + sh_ap_PER_CPU *per_cpu; +} sh_ap_CPU_STRUCT; +#pragma pack() +// Allocate each sets of stacks for each TSS and each C stack, create each TSS entry, create global GDT64, create the CPU structure area, create and fill each CPU structure, create the AP bootstrap structure and place it correctly +SH_STATUS sh_ap_prepare_for_smp_launch(sh_lapic_DEVICE **lapic_dev_array,sh_uint64 max_lapic_id,sh_uint64 expected_lapic_found,sh_conf_BOOT_CONFIG *boot_config,sh_idt_IDT *idt); +// AP C entry point +void sh_ap_entry_point(); +// Start AP boot procedure +SH_STATUS sh_ap_start_ap_boot_procedure(sh_conf_BOOT_CONFIG *boot_config); +#endif diff --git a/shelter/lib/include/cpu/asm.h b/shelter/lib/include/cpu/asm.h index 23a064a..a5420ec 100644 --- a/shelter/lib/include/cpu/asm.h +++ b/shelter/lib/include/cpu/asm.h @@ -3,14 +3,17 @@ #define SH_LIB_ASM_H #include "std/type.h" #include "std/status.h" +#include "irq/gdt.h" +#include "irq/tss.h" +#include "irq/idt.h" // inb instruction wrapper -static inline sh_uint8 sh_asm_inb(sh_uint16 port) { +inline sh_uint8 sh_asm_inb(sh_uint16 port) { sh_uint8 val; __asm__ volatile ("inb %1, %0":"=a"(val):"Nd"(port)); return val; } // outb instruction wrapper -static inline void sh_asm_outb(sh_uint16 port,sh_uint8 val) { +inline void sh_asm_outb(sh_uint16 port,sh_uint8 val) { __asm__ volatile ("outb %0, %1"::"a"(val),"Nd"(port)); } // rdtsc instruction wrapper @@ -23,4 +26,44 @@ static inline sh_uint64 sh_asm_rdtsc() { static inline void sh_asm_invlpg(void *addr) { __asm__ volatile ("invlpg (%0)"::"r"(addr):"memory"); } +// lgdt instruction wrapper +static inline void sh_asm_lgdt(sh_gdt_GDTR gdtr) { + __asm__ volatile ("lgdt %0"::"m"(gdtr):"memory"); +} +// ltr instruction wrapper +static inline void sh_asm_ltr(sh_uint16 tss_selector) { + __asm__ volatile ("ltr %0"::"r"(tss_selector):"memory"); +} +// lidt instruction wrapper +static inline void sh_asm_lidt(sh_idt_IDTR idtr) { + __asm__ volatile ("lidt %0"::"m"(idtr):"memory"); +} +// sidt instruction wrapper +static inline void sh_asm_sidt(sh_idt_IDTR* idtr) { + __asm__ volatile ("sidt %0":"=m"(*idtr)::"memory"); +} +// sti instruction wrapper +static inline void sh_asm_sti() { + __asm__ volatile ("sti"); +} +// cli instruction wrapper +static inline void sh_asm_cli() { + __asm__ volatile ("cli"); +} +// cpuid instruction wrapper +static inline void sh_asm_cpuid(sh_uint32 leaf,sh_uint32 subleaf,sh_uint32 *eax,sh_uint32 *ebx,sh_uint32 *ecx,sh_uint32 *edx){ + __asm__ volatile ("cpuid":"=a"(*eax),"=b"(*ebx),"=c"(*ecx),"=d"(*edx):"a"(leaf),"c"(subleaf)); +} +// mfence instruction wrapper +inline void sh_asm_mfence() { + __asm__ volatile("mfence":::"memory"); +} +// lfence instruction wrapper +inline void sh_asm_lfence() { + __asm__ volatile("lfence":::"memory"); +} +// sfence instruction wrapper +inline void sh_asm_sfence() { + __asm__ volatile("sfence":::"memory"); +} #endif diff --git a/shelter/lib/include/cpu/pic.h b/shelter/lib/include/cpu/pic.h new file mode 100644 index 0000000..d96761d --- /dev/null +++ b/shelter/lib/include/cpu/pic.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_PIC_H +#define SH_LIB_PIC_H +#include "std/stdlib.h" +#define SH_PIC1_CMD 0x20 +#define SH_PIC1_DATA 0x21 +#define SH_PIC2_CMD 0xA0 +#define SH_PIC2_DATA 0xA1 +// Remap all PIC interrupts on interrupts vectors 32 to 47, leave only IRQ0 enabled +void sh_pic_remap(); +// Unmask a PIC interrupt +void sh_pic_unmask(sh_uint8 irq); +// Mask a PIC interrupt +void sh_pic_mask(sh_uint8 irq); +// Send EOI to PIC +void sh_pic_send_eoi(sh_uint8 irq); +#endif diff --git a/shelter/lib/include/cpu/pit.h b/shelter/lib/include/cpu/pit.h new file mode 100644 index 0000000..eed371c --- /dev/null +++ b/shelter/lib/include/cpu/pit.h @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_PIT_H +#define SH_LIB_PIT_H +#include "std/stdlib.h" +// Set PIT frequency +void sh_pit_set_frequency(sh_uint64 hz); +#endif diff --git a/shelter/lib/include/cpu/tsc.h b/shelter/lib/include/cpu/tsc.h index 0e57e61..72ff256 100644 --- a/shelter/lib/include/cpu/tsc.h +++ b/shelter/lib/include/cpu/tsc.h @@ -4,6 +4,7 @@ #include "std/type.h" #include "std/status.h" #include "cpu/asm.h" +#include "devs/devs.h" typedef sh_uint64 sh_tsc_TSC_VALUE; // Reas TSC register. static inline sh_tsc_TSC_VALUE sh_tsc_read_tsc() { @@ -15,4 +16,16 @@ SH_STATUS sh_tsc_init_tsc(); sh_tsc_TSC_VALUE sh_tsc_get_kernel_init_tsc(); // Return kernel current tsc. sh_tsc_TSC_VALUE sh_tsc_get_kernel_current_tsc(); +// Estimate CPU frequency using TSC and PIT +sh_uint64 sh_tsc_estimate_cpu_freq(); +// Load CPU frequency +void sh_tsc_load_cpu_freq(sh_uint64 cpu_freq); +// Detect if CPUID provide hypervisor bit +sh_bool sh_tsc_has_hypervisor(); +// Detect if CPUID provide TSC constant bit +sh_bool sh_tsc_is_tsc_constant(); +// Return CPUID CPU frequence if available +SH_STATUS sh_tsc_get_cpu_freq_cpuid(sh_uint64 *freq); +// Parse a TSC DevS query +SH_STATUS sh_tsc_devs_query(char *sub_path,sh_devs_RESULT *result); #endif diff --git a/shelter/lib/include/devs/acpi.h b/shelter/lib/include/devs/acpi.h new file mode 100644 index 0000000..6b63a7f --- /dev/null +++ b/shelter/lib/include/devs/acpi.h @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_ACPI_H +#define SH_LIB_ACPI_H +#include "std/stdlib.h" +// ACPI v1 RSDP structure +typedef struct { + sh_uint8 signature[8]; + sh_uint8 checksum; + sh_uint8 oem_id[6]; + sh_uint8 revision; + sh_uint32 rsdt_address; +} sh_acpi_RSDP_V1; +// ACPI v2 RSDP structure +typedef struct { + sh_acpi_RSDP_V1 first_part; + sh_uint32 length; + sh_uint64 xsdt_address; + sh_uint8 extended_checksum; + sh_uint8 reserved[3]; +} sh_acpi_RSDP_V2; +// ACPI pointers root structure +typedef struct { + sh_uint64 rsdt; + sh_uint64 xsdt; // set to 0 if ACPI v2 isn't supported +} sh_apci_ACPI_POINTERS_ROOT; +// ACPI XSDT header +typedef struct { + char signature[4]; + sh_uint32 length; + sh_uint8 revision; + sh_uint8 checksum; + char oem_id[6]; + char oem_table_id[8]; + sh_uint32 oem_revision; + sh_uint32 creator_id; + sh_uint32 creator_revision; +} sh_acpi_ACPI_XSDT_HEADER; +// ACPI XSTD body +typedef struct { + sh_uint64 *entries; + sh_uint64 entry_count; +} sh_acpi_ACPI_XSDT_BODY; +// ACPI tables list +typedef struct { + sh_uint64 madt_physical_address; +} sh_acpi_ACPI_TABLES; +// ACPI table header +typedef struct { + char signature[4]; + sh_uint32 length; + sh_uint8 revision; + sh_uint8 checksum; + char oem_id[6]; + char oem_table_id[8]; + sh_uint32 oem_revision; + sh_uint32 creator_id; + sh_uint32 creator_revision; +} sh_acpi_TABLE_HEADER; +// Try to obtain ACPI root pointer +SH_STATUS sh_acpi_parse_rsdp(sh_uint64 rsdp,sh_uint8 acpi_ver,sh_apci_ACPI_POINTERS_ROOT *out); +// Parse XSDT header and ensure that all entries are mapped +SH_STATUS sh_acpi_parse_xsdt(sh_uint64 xsdt,sh_acpi_ACPI_XSDT_BODY *xsdt_body); +// Parse XSDT entries, ensure that all the headers of each table is mapped and sort all entries into their respectives fields inside acpi_tables. Doesn't parse each table header +SH_STATUS sh_acpi_parse_tables(sh_acpi_ACPI_XSDT_BODY *xsdt_body,sh_acpi_ACPI_TABLES *acpi_tables); +#endif diff --git a/shelter/lib/include/devs/acpi_tables/madt.h b/shelter/lib/include/devs/acpi_tables/madt.h new file mode 100644 index 0000000..891f0c2 --- /dev/null +++ b/shelter/lib/include/devs/acpi_tables/madt.h @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_ACPI_MADT_H +#define SH_LIB_ACPI_MADT_H +#include "std/stdlib.h" +// MADT header structure +typedef struct { + char signature[4]; + sh_uint32 length; + sh_uint8 revision; + sh_uint8 checksum; + char oem_id[6]; + char oem_table_id[8]; + sh_uint32 oem_revision; + sh_uint32 creator_id; + sh_uint32 creator_revision; +} sh_acpi_madt_TABLE_HEADER; +// MADT structure +typedef struct { + sh_acpi_madt_TABLE_HEADER header; + sh_uint32 local_apic_address; + sh_uint32 flags; +} sh_acpi_madt_MADT; +// MADT entry header structure +typedef struct { + sh_uint8 type; + sh_uint8 length; +} sh_acpi_madt_ENTRY_HEADER; +// Local APIC structure +typedef struct { + sh_acpi_madt_ENTRY_HEADER header; + sh_uint8 acpi_processor_id; + sh_uint8 apic_id; + sh_uint32 flags; +} sh_acpi_madt_LAPIC; +// IO APIC structure +typedef struct { + sh_acpi_madt_ENTRY_HEADER header; + sh_uint8 ioapic_id; + sh_uint8 reserved; + sh_uint32 ioapic_address; + sh_uint32 global_system_interrupt_base; +} sh_acpi_madt_IOAPIC; +// Interrupt source override structure +typedef struct { + sh_acpi_madt_ENTRY_HEADER header; + sh_uint8 bus; + sh_uint8 source; + sh_uint32 gsi; + sh_uint16 flags; +} sh_acpi_madt_ISO; +// Parse MADT table +SH_STATUS sh_acpi_madt_parse(sh_uint64 madt_ptr); +#endif diff --git a/shelter/lib/include/devs/apic/ioapic.h b/shelter/lib/include/devs/apic/ioapic.h new file mode 100644 index 0000000..b1f9d9e --- /dev/null +++ b/shelter/lib/include/devs/apic/ioapic.h @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_IOAPIC_H +#define SH_LIB_IOAPIC_H +#include "std/stdlib.h" +#include "memory/page.h" +#define SH_IOAPIC_OFFSET_IOREGSEL 0x00 +#define SH_IOAPIC_OFFSET_IOWIN 0x10 +#define SH_IOAPIC_REGISTER_IOAPICID 0x00 +#define SH_IOAPIC_REGISTER_IOAPICVER 0x01 +#define SH_IOAPIC_REGISTER_IOAPICARB 0x02 +#define SH_IOAPIC_REGISTER_IOREDTBL_BASE 0x10 +// IOAPIC device structure +typedef struct { + volatile sh_uint32 *base; + sh_uint8 ioapic_id; + sh_uint32 gsi_base; + sh_uint32 gsi_count; // must be completed by reading the IOAPICVER register in the sh_ioapic_init call + sh_SPIN_LOCK lock; +} sh_ioapic_DEVICE; +// Initialize an IOAPIC device structure, intented to initialize all IOAPIC devices structures during MADT parsing +SH_STATUS sh_ioapic_init(sh_uint32 base,sh_uint8 ioapic_id,sh_uint32 gsi_base,sh_ioapic_DEVICE *ioapic); +// Initialize DevS IOAPIC backend (max_ioapic_id is the max IOAPIC id, not the number of IOAPIC counted) +SH_STATUS sh_ioapic_init_devs(sh_uint8 max_ioapic_id); +// Bind a LAPIC device to DevS LAPIC backend +SH_STATUS sh_ioapic_bind(sh_ioapic_DEVICE *lapic_dev); +// Return a pointer to an IOAPIC device based on the provided IOAPIC id +sh_ioapic_DEVICE *sh_ioapic_get_dev_ioapic_id(sh_uint64 ioapic_id); +#define SH_IOAPIC_IOREDTBL_DELIVERY_FIXED 0b000 +#define SH_IOAPIC_IOREDTBL_DELIVERY_LOWEST_PRIORITY 0b001 +#define SH_IOAPIC_IOREDTBL_DELIVERY_NMI 0b100 +#define SH_IOAPIC_IOREDTBL_DELIVERY_INIT 0b101 +#define SH_IOAPIC_IOREDTBL_DELIVERY_EXTINT 0b111 +#define SH_IOAPIC_IOREDTBL_TRIGGER_EDGE 0b0 +#define SH_IOAPIC_IOREDTBL_TRIGGER_LEVEL 0b1 +#define SH_IOAPIC_IOREDTBL_POLARITY_HIGH 0b0 +#define SH_IOAPIC_IOREDTBL_POLARITY_LOW 0b1 +#define SH_IOAPIC_IOREDTBL_DEST_MODE_PHYSICAL 0b0 +#define SH_IOAPIC_IOREDTBL_DEST_MODE_LOGICAL 0b1 +// IOREDTBL entry structure +typedef struct { + sh_uint32 low; + sh_uint32 high; +} sh_ioapic_IOREDTBL_ENTRY; +// Create an IOREDTBL entry +inline sh_ioapic_IOREDTBL_ENTRY sh_ioapic_make_ioredtbl_entry(sh_uint8 vector,sh_uint8 delivery_mode,sh_uint8 destination_mode,sh_uint8 polarity,sh_uint8 trigger_mode,sh_bool mask,sh_uint8 apic_id) { + sh_ioapic_IOREDTBL_ENTRY e={0}; + e.low=(e.low& ~0xFFU)|vector; + e.low=(e.low& ~(0x7U<<8))|((delivery_mode&0x7U)<<8); + e.low=(e.low& ~(1U<<11))|((destination_mode&0x1U)<<11); + e.low=(e.low& ~(1U<<13))|((polarity&0x1U)<<13); + e.low=(e.low& ~(1U<<15))|((trigger_mode&0x1U)<<15); + e.low=(e.low& ~(1U<<16))|((mask&0x1U)<<16); + e.high=(e.high& ~(0xFFU<<24))|((sh_uint32)apic_id<<24); + return e; +} +// Mask an IOREDTBL entry for the provided GSI +SH_STATUS sh_ioapic_mask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi); +// Unmask an IOREDTBL entry for the provided GSI +SH_STATUS sh_ioapic_unmask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi); +// Read an IOREDTBL entry for the provided GSI +SH_STATUS sh_ioapic_read_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry); +// Write an IOREDTBL entry for the provided GSI +SH_STATUS sh_ioapic_write_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry); +// Mask all IOREDTBL entries for all IOAPIC +SH_STATUS sh_ioapic_mask_all(); +// Return the IOAPIC device corresponding to the provided GSI +sh_ioapic_DEVICE *sh_ioapic_get_dev_by_gsi(sh_uint32 gsi); +// Parse an IOAPIC DevS query +SH_STATUS sh_ioapic_devs_query(char *sub_path,sh_devs_RESULT *result); +#endif diff --git a/shelter/lib/include/devs/apic/lapic.h b/shelter/lib/include/devs/apic/lapic.h new file mode 100644 index 0000000..469ccb1 --- /dev/null +++ b/shelter/lib/include/devs/apic/lapic.h @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_LAPIC_H +#define SH_LIB_LAPIC_H +#include "std/status.h" +#include "std/type.h" +#include "memory/page.h" +#include "devs/devs.h" +#define SH_LAPIC_OFFSET_ID 0x020 +#define SH_LAPIC_OFFSET_VERSION 0x030 +#define SH_LAPIC_OFFSET_EOI 0x0B0 +#define SH_LAPIC_OFFSET_SVR 0x0F0 +#define SH_LAPIC_OFFSET_ESR 0x280 +#define SH_LAPIC_OFFSET_ICR_LOW 0x300 +#define SH_LAPIC_OFFSET_ICR_HIGH 0x310 +#define SH_LAPIC_OFFSET_LVT_TIMER 0x320 +#define SH_LAPIC_OFFSET_LVT_ERROR 0x370 +#define SH_LAPIC_OFFSET_TIMER_INIT 0x380 +#define SH_LAPIC_OFFSET_TIMER_CURR 0x390 +#define SH_LAPIC_OFFSET_TIMER_DIV 0x3E0 +#define SH_LAPIC_TIMER_DIVIDER 0x3 +// LAPIC device structure +typedef struct { + volatile sh_uint32 *base; + sh_uint8 apic_id; + sh_uint8 acpi_processor_id; + sh_uint32 flags; + sh_uint32 spurious_vector; +} sh_lapic_DEVICE; +// Initialize a LAPIC device structure, intented to initialize all LAPIC devices structures during MADT parsing +SH_STATUS sh_lapic_init(sh_uint64 lapic_phys,sh_uint8 spurious_vector,sh_uint8 apic_id,sh_uint8 apic_processor_id,sh_uint32 flags,sh_lapic_DEVICE *lapic); +// Initialize LAPIC for this CPU, intended to be used once by each CPU +SH_STATUS sh_lapic_init_dev(sh_uint8 spurious_vector,sh_lapic_DEVICE *lapic); +// Initialize DevS LAPIC backend (max_lapic_id is the max LAPIC id, not the number of LAPIC counted) +SH_STATUS sh_lapic_init_devs(sh_uint16 max_lapic_id,sh_uint16 max_acpi_processor_id); +// Bind a LAPIC device to DevS LAPIC backend +SH_STATUS sh_lapic_bind(sh_lapic_DEVICE *lapic_dev); +// Write 0 in provided LAPIC device EOI register +void sh_lapic_eoi(sh_lapic_DEVICE *lapic); +// Return a pointer to a LAPIC device based on the provided APIC id +sh_lapic_DEVICE *sh_lapic_get_dev_apic_id(sh_uint64 apic_id); +// Return a pointer to a LAPIC device based on the provided ACPI processor id +sh_lapic_DEVICE *sh_lapic_get_dev_acpi_cpu_id(sh_uint64 acpi_processor_id); +// Launch a LAPIC one-shot timer, independantely of the calibrated state of the LAPIC +SH_STATUS sh_lapic_timer_one_shot(sh_lapic_DEVICE *lapic_dev,sh_uint32 initial_value); +// Calibrate the LAPIC frequency +SH_STATUS sh_lapic_calibrate(sh_lapic_DEVICE *lapic_dev,sh_uint64 cpu_freq); +// Return the LAPIC frequency +sh_uint64 sh_lapic_get_frequency(); +// Launch a LAPIC one-shot timer, LAPIC frequency need to be set +SH_STATUS sh_lapic_timer_one_shot_us(sh_lapic_DEVICE *lapic_dev,sh_uint64 microseconds_count); +// Return LAPIC DevS array +sh_lapic_DEVICE **sh_lapic_get_by_apic_id_array(); +// Return max LAPIC APIC id +sh_uint64 sh_lapic_get_max_apic_id(); +// Return max ACPI processor id +sh_uint64 sh_lapic_get_max_acpi_processor_id(); +// Return LAPIC count +sh_uint64 sh_lapic_get_lapic_count(); +#define SH_LAPIC_IPI_TYPE_NMI 0b100 +#define SH_LAPIC_IPI_TYPE_INIT 0b101 +#define SH_LAPIC_IPI_TYPE_STARTUP 0b110 +#define SH_LAPIC_IPI_TYPE_FIXED 0b000 +#define SH_LAPIC_IPI_DESTINATION_SPECIFIC (0b00<<18) +#define SH_LAPIC_IPI_DESTINATION_SELF (0b01<<18) +#define SH_LAPIC_IPI_DESTINATION_ALL (0b10<<18) +#define SH_LAPIC_IPI_DESTINATION_ALL_EXCLUDING_SELF (0b11<<18) +#define SH_LAPIC_IPI_NO_DESTINATION (sh_int16)(-1) +// Return SH_TRUE if LAPIC IPI feature is busy +sh_bool sh_lapic_ipi_is_busy(sh_lapic_DEVICE *lapic_dev); +// Return LAPIC id of current core, return -1 if error happened +sh_int16 sh_lapic_get_current_core(); +// Send a fixed IPI with the specified vector. lapic_dev must be the struct of the current CPU. +// If destination_mode!=SH_LAPIC_IPI_DESTINATION_SPECIFIC, target_lapic_id must be SH_LAPIC_IPI_NO_DESTINATION +SH_STATUS sh_lapic_send_fixed_ipi(sh_lapic_DEVICE *lapic_dev,sh_uint8 vector,sh_uint32 destination_mode,sh_int16 target_lapic_id); +// Send any IPI other than a fixed IPI to specified destination. lapic_dev must be the struct of the current CPU. +// ipi_type must be either SH_LAPIC_IPI_TYPE_INIT, SH_LAPIC_IPI_TYPE_STARTUP or SH_LAPIC_IPI_TYPE_NMI +// If ipi_type is SH_LAPIC_IPI_TYPE_STARTUP, start_address must contain the starting address. Address constraint (compatible with 16 bits mode) are checked. +// If ipi_type isn't SH_LAPIC_IPI_TYPE_STARTUP, start_address must be zero. +// If destination_mode!=SH_LAPIC_IPI_DESTINATION_SPECIFIC, target_lapic_id must be SH_LAPIC_IPI_NO_DESTINATION +SH_STATUS sh_lapic_send_ipi(sh_lapic_DEVICE *lapic_dev,sh_uint32 ipi_type,sh_uint32 destination_mode,sh_int16 target_lapic_id,sh_page_PHYSICAL_ADDRESS start_address); +// Parse a LAPIC DevS query +SH_STATUS sh_lapic_devs_query(char *sub_path,sh_devs_RESULT *result); +#endif diff --git a/shelter/lib/include/devs/devs.h b/shelter/lib/include/devs/devs.h new file mode 100644 index 0000000..f1f2fbe --- /dev/null +++ b/shelter/lib/include/devs/devs.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_DEVS_H +#define SH_LIB_DEVS_H +#include "std/status.h" +#include "std/type.h" +#include "std/string.h" +// DevS result type enum +enum sh_devs_RESULT_TYPE { + SH_DEVS_LAPIC, + SH_DEVS_IOAPIC, + SH_DEVS_VALUE, + SH_DEVS_BOOL +}; +// DevS result structure +typedef struct { + enum sh_devs_RESULT_TYPE type; + sh_uint64 value; +} sh_devs_RESULT; +// Parse a DevS query +SH_STATUS sh_devs_query(char *path,sh_devs_RESULT *result); +#endif diff --git a/shelter/lib/include/devs/input/event.h b/shelter/lib/include/devs/input/event.h new file mode 100644 index 0000000..ed6c90a --- /dev/null +++ b/shelter/lib/include/devs/input/event.h @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_EVENT_H +#define SH_LIB_EVENT_H +#include "std/type.h" +// Events types +typedef sh_uint8 sh_event_TYPE; +#define SH_EVENT_TYPE_PS2_NORMAL 0U +#define SH_EVENT_TYPE_PS2_E0 1U +#define SH_EVENT_TYPE_KBD_CONTEXT 2U +#define SH_EVENT_TYPE_KBD_PAUSE 3U +// Keyboard events context flags +#define SH_KBD_EVENT_SHIFT_ACTIVE (1u<<0) +#define SH_KBD_EVENT_WIN_ACTIVE (1u<<1) +#define SH_KBD_EVENT_LEFT_ACTIVE (1u<<1) +#define SH_KBD_EVENT_RIGHT_ACTIVE (1u<<0) +#define SH_KBD_EVENT_NUMLOCK_ACTIVE (1u<<0) +#define SH_KBD_EVENT_CAPSLOCK_ACTIVE (1u<<1) +// Keyboard contexts key scancodes +#define SH_KBD_CONTEXT_LSHIFT 0U +#define SH_KBD_CONTEXT_RSHIFT 1U +#define SH_KBD_CONTEXT_LCTRL 2U +#define SH_KBD_CONTEXT_RCTRL 3U +#define SH_KBD_CONTEXT_LALT 4U +#define SH_KBD_CONTEXT_RALT 5U +#define SH_KBD_CONTEXT_WIN 6U +#define SH_KBD_CONTEXT_NUMLOCK 7U +#define SH_KBD_CONTEXT_CAPSLOCK 8U +// Keyboard event structure +typedef struct { + sh_uint16 scancode; + sh_bool pressed; + sh_uint8 context_shift_win; + sh_uint8 context_alt; + sh_uint8 context_ctrl; + sh_uint8 context_lock_status; + sh_uint8 event_type; + sh_uint64 timestamp; // tsc +} sh_kbd_EVENT; +#endif diff --git a/shelter/lib/include/devs/input/kbd.h b/shelter/lib/include/devs/input/kbd.h new file mode 100644 index 0000000..458ac46 --- /dev/null +++ b/shelter/lib/include/devs/input/kbd.h @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_KBD_H +#define SH_LIB_KBD_H +#include "std/stdlib.h" +#include "devs/input/event.h" +// Keyboard driver handle structure, driver handles should only be owned by keyboards drivers +typedef struct sh_kbd_DRIVER_HANDLE sh_kbd_DRIVER_HANDLE; +// Keyboard consumer handle structure, used for requests made by consumer +typedef struct sh_kbd_CONSUMER_HANDLE sh_kbd_CONSUMER_HANDLE; +// Keyboard device structure +typedef struct { + sh_uint8 kbd_id; + sh_queue_KBD_EVENT *events_queue; + sh_bool present; + sh_bool ver_maj; + sh_bool ver_num; + sh_bool shift; + sh_bool alt; + sh_bool ctrl; + sh_bool win; + sh_SPIN_LOCK spinlock; +} sh_kbd_DEVICE; +// Initialize Keyboard input subsystem, should only be called one time +SH_STATUS sh_kbd_init_devs(); +// Register the PS2 keyboard, completing the provided handle. +SH_STATUS sh_kbd_register_ps2(sh_bool is_present,sh_kbd_DRIVER_HANDLE **handle); +// Register any others keyboard, completing the provided handle, that should be used only by the keyboard driver for using the keyboard subsystem API +SH_STATUS sh_kbd_register(sh_bool is_present,sh_kbd_DRIVER_HANDLE **handle); +#define SH_KBD_FLAG_PRESENT 0U +#define SH_KBD_FLAG_VER_MAJ 1U +#define SH_KBD_FLAG_VER_NUM 2U +#define SH_KBD_FLAG_SHIFT 3U +#define SH_KBD_FLAG_ALT 4U +#define SH_KBD_FLAG_CTRL 5U +#define SH_KBD_FLAG_WIN 6U +// Set any flag in the sh_kbd_DEVICE struct, given that a correct handle has been provided +SH_STATUS sh_kbd_set_flag(sh_kbd_DRIVER_HANDLE *handle,sh_uint8 flag,sh_bool value); +// Push a keyboard event on the keyboard queue, given that a correct handle has been provided +SH_STATUS sh_kbd_push_events(sh_kbd_DRIVER_HANDLE *handle,sh_kbd_EVENT *event); +// Keyboard device enumeration structure +typedef struct { + sh_uint64 bitmap[4]; +} sh_kbd_ENUMERATION; +// Enumerate all keyboard devices id +SH_STATUS sh_kbd_enumerate_devices(sh_kbd_ENUMERATION *enumeration); +// Return a valid consumer handle for the provided keyboard device id +SH_STATUS sh_kbd_get_handle(sh_uint8 kbd_id,sh_kbd_CONSUMER_HANDLE **handle); +// Destroy the provided consumer handle and set the pointer to SH_NULLPTR +SH_STATUS sh_kbd_destroy_handle(sh_kbd_CONSUMER_HANDLE **handle); +// Read any flag in the sh_kbd_DEVICE struct, given that a correct handle has been provided. Accept either a driver or consumer handle, but fail if both handle are provided +SH_STATUS sh_kbd_read_flag(sh_kbd_DRIVER_HANDLE *d_handle,sh_kbd_CONSUMER_HANDLE *c_handle,sh_uint8 flag,sh_bool *value); +#endif diff --git a/shelter/lib/include/devs/input/ps2.h b/shelter/lib/include/devs/input/ps2.h new file mode 100644 index 0000000..2f196b4 --- /dev/null +++ b/shelter/lib/include/devs/input/ps2.h @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_PS2_H +#define SH_LIB_PS2_H +#include "std/stdlib.h" +#include "devs/input/event.h" +#include "devs/input/kbd.h" +// Port macros +#define SH_PS2_PORT_DATA 0x60 +#define SH_PS2_PORT_COMMAND 0x64 +// Status byte bits +#define SH_PS2_STATUS_OBF 0b1 +#define SH_PS2_STATUS_IBF 0b10 +#define SH_PS2_STATUS_MOUSE_DATA 0b100000 +#define SH_PS2_STATUS_TIMEOUT 0b1000000 +#define SH_PS2_STATUS_PARITY 0b10000000 +// Config byte bits +#define SH_PS2_CONFIG_PORT1_IRQ 0b1 +#define SH_PS2_CONFIG_PORT2_IRQ 0b10 +#define SH_PS2_CONFIG_PORT1_CLOCK_DISABLED 0b10000 +#define SH_PS2_CONFIG_PORT2_CLOCK_DISABLED 0b100000 +#define SH_PS2_CONFIG_TRANSLATION 0b1000000 +// PS2 controller commands macros +#define SH_PS2_COMMAND_READ_CONFIG 0x20 +#define SH_PS2_COMMAND_WRITE_CONFIG 0x60 +#define SH_PS2_COMMAND_PS2_SELF_TEST 0xAA +#define SH_PS2_COMMAND_PORT1_TEST 0xAB +#define SH_PS2_COMMAND_PORT2_DISABLE 0xA7 +#define SH_PS2_COMMAND_PORT2_ENABLE 0xA8 +#define SH_PS2_COMMAND_PORT2_TEST 0xA9 +#define SH_PS2_COMMAND_PORT1_DISABLE 0xAD +#define SH_PS2_COMMAND_PORT1_ENABLE 0xAE +#define SH_PS2_COMMAND_READ_OUTPUT 0xD0 +#define SH_PS2_COMMAND_WRITE_OUTPUT 0xD1 +#define SH_PS2_COMMAND_WRITE_PORT2 0xD4 +// Self test results macros +#define SH_PS2_SELF_TEST_SUCCESS 0x55 +#define SH_PS2_SELF_TEST_FAIL 0xFC +#define SH_PS2_PORTS_SELF_TEST_SUCCESS 0x00 +// PS2 keyboard commands macros +#define SH_PS2_KBD_COMMAND_SET_LEDS 0xED +#define SH_PS2_KBD_COMMAND_ECHO 0xEE +#define SH_PS2_KBD_COMMAND_SC_SET 0xF0 +#define SH_PS2_KBD_COMMAND_IDENTIFY 0xF2 +#define SH_PS2_KBD_COMMAND_ENABLE_SCANNING 0xF4 +#define SH_PS2_KBD_COMMAND_DISABLE_SCANNING 0xF5 +#define SH_PS2_KBD_COMMAND_DEFAULTS 0xF6 +#define SH_PS2_KBD_COMMAND_RESET 0xFF +// Leds bits +#define SH_PS2_KBD_LEDS_SCROLL_LOCK 0b1 +#define SH_PS2_KBD_LEDS_NUM_LOCK 0b10 +#define SH_PS2_KBD_LEDS_CAPS_LOCK 0b100 +// Scancodes (SC) sets +#define SH_PS2_KBD_SC_SET_CURRENT 0 +#define SH_PS2_KBD_SC_SET_1 1 +#define SH_PS2_KBD_SC_SET_2 2 +#define SH_PS2_KBD_SC_SET_3 3 +// Keyboard response macros +#define SH_PS2_KBD_ACK 0xFA +#define SH_PS2_KBD_RESEND 0xFE +#define SH_PS2_KBD_BAT_SUCCESS 0xAA +#define SH_PS2_KBD_BAT_FAIL 0xFC +#define SH_PS2_KBD_ECHO_REPLY 0xEE +// Return SH_TRUE if data port contain useful datas to read +inline sh_bool sh_ps2_output_ready() { + return sh_asm_inb(SH_PS2_PORT_COMMAND) & SH_PS2_STATUS_OBF; +} +// Return SH_TRUE if controller isn't ready for any output +inline sh_bool sh_ps2_cant_write() { + return sh_asm_inb(SH_PS2_PORT_COMMAND) & SH_PS2_STATUS_IBF; +} +// Keyboard command struct +typedef struct { + sh_uint8 command; + sh_uint8 data; + sh_bool has_data; +} sh_ps2_KBD_COMMAND; +// Read status byte +inline sh_uint8 sh_ps2_read_status() { + return sh_asm_inb(SH_PS2_PORT_COMMAND); +} +// Read config byte +inline sh_uint8 sh_ps2_read_config() { + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_READ_CONFIG); + while (!sh_ps2_output_ready()); + return sh_asm_inb(SH_PS2_PORT_DATA); +} +// Write config byte +inline void sh_ps2_write_config(sh_uint8 config) { + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_WRITE_CONFIG); + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_DATA,config); +} +// PS2 IRQ1 handler +void sh_ps2_irq1_handler(); +// Send a keyboard command and wait for it to finish +SH_STATUS sh_ps2_send_keyboard_command_wait(sh_uint8 cmd,sh_uint8 data,sh_bool has_data); +// Initialize the PS2 driver +SH_STATUS sh_ps2_driver_init(); +// Disable scanning +SH_STATUS sh_ps2_disable_scanning(); +// Enable scanning +SH_STATUS sh_ps2_enable_scanning(); +#endif diff --git a/shelter/lib/include/irq/gdt.h b/shelter/lib/include/irq/gdt.h new file mode 100644 index 0000000..d12a36a --- /dev/null +++ b/shelter/lib/include/irq/gdt.h @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_GDT_H +#define SH_LIB_GDT_H +#include "std/status.h" +#include "std/type.h" +#include "irq/tss.h" +// Long mode GDT part +// GDT entry 64 bits structure +#pragma pack(1) +typedef struct { + sh_uint16 limit_low; + sh_uint16 base_low; + sh_uint8 base_mid; + sh_uint8 access; + sh_uint8 flags_limit_high; + sh_uint8 base_high; +} sh_gdt_GDT_ENTRY_64; +#pragma pack() +// GDT entry 128 bits (special TSS) structure +#pragma pack(1) +typedef struct { + sh_uint16 limit_low; + sh_uint16 base_low; + sh_uint8 base_mid; + sh_uint8 access; + sh_uint8 flags_limit_high; + sh_uint8 base_high; + sh_uint32 base_upper; + sh_uint32 reserved; +} sh_gdt_GDT_ENTRY_128; +#pragma pack() +// GDTR structure +#pragma pack(1) +typedef struct { + sh_uint16 limit; + sh_uint64 base; +} sh_gdt_GDTR; +#pragma pack() +// GDT structure for bootstrap core +#pragma pack(1) +typedef struct { + sh_gdt_GDT_ENTRY_64 null; + sh_gdt_GDT_ENTRY_64 kernel_code; + sh_gdt_GDT_ENTRY_64 kernel_data; + sh_gdt_GDT_ENTRY_64 user_code; + sh_gdt_GDT_ENTRY_64 user_data; + sh_gdt_GDT_ENTRY_128 tss; +} sh_gdt_GDT; +#pragma pack() +// GDT structure for all APs +#pragma pack(1) +typedef struct { + sh_gdt_GDT_ENTRY_64 null; + sh_gdt_GDT_ENTRY_64 kernel_code; + sh_gdt_GDT_ENTRY_64 kernel_data; + sh_gdt_GDT_ENTRY_64 user_code; + sh_gdt_GDT_ENTRY_64 user_data; + sh_gdt_GDT_ENTRY_128 tss[256]; +} sh_gdt_GDT_AP; +#pragma pack() +// Generate access byte +inline sh_uint8 sh_gdt_fill_access_byte(sh_bool present,sh_uint8 dpl,sh_bool descriptor_type,sh_uint8 segment_type) { + return ((present?1:0)<<7)|((dpl&0x3)<<5)|((descriptor_type?1:0)<<4)|(segment_type&0xF); +} +// Generate flags byte (put all 4 bits in bit 0-3 of the returned byte) +inline sh_uint8 sh_gdt_fill_flags_byte(sh_bool g,sh_bool db,sh_bool l,sh_bool avl) { + return ((g?1:0)<<3)|((db?1:0)<<2)|((l?1:0)<<1)|((avl?1:0)<<0); +} +// Fill GDT entry 64 bits, expect flags as sh_gdt_fill_flags_byte would return it +sh_gdt_GDT_ENTRY_64 sh_gdt_fill_gdt_entry_64(sh_uint32 limit,sh_uint32 base,sh_uint8 access,sh_uint8 flags); +// Fill GDT entry 128 bits, expect flags as sh_gdt_fill_flags_byte would return it +sh_gdt_GDT_ENTRY_128 sh_gdt_fill_gdt_entry_128(sh_uint32 limit,sh_uint64 base,sh_uint8 access,sh_uint8 flags); +// Fill GDT with provided TSS +SH_STATUS sh_gdt_fill_gdt(sh_tss_TSS *tss,sh_gdt_GDT *gdt); +// Fill APs common GDT with provided TSS array +SH_STATUS sh_gdt_fill_gdt_ap(sh_tss_TSS *tss,sh_uint64 tss_count,sh_gdt_GDT_AP *gdt); +// Generate GDTR for AP GDT +sh_gdt_GDTR sh_gdt_make_gdtr_ap(sh_gdt_GDT_AP *gdt); +// Fill and load GDTR +SH_STATUS sh_gdt_load_gdtr(sh_gdt_GDT *gdt); +// Reload registers +SH_STATUS sh_gdt_reload_registers(); +// 16/32 bits mode GDT part +// GDT entry 32 bits structure +#pragma pack(1) +typedef struct { + sh_uint16 limit_low; + sh_uint16 base_low; + sh_uint8 base_middle; + sh_uint8 access; + sh_uint8 granularity; + sh_uint8 base_high; +} sh_gdt_GDT_ENTRY_32; +#pragma pack() +// GDT 32 bits structure +#pragma pack(1) +typedef struct { + sh_gdt_GDT_ENTRY_32 null; + sh_gdt_GDT_ENTRY_32 code_64; + sh_gdt_GDT_ENTRY_32 code; + sh_gdt_GDT_ENTRY_32 data; +} sh_gdt_GDT_32; +#pragma pack() +// Generate access byte +inline sh_uint8 sh_gdt_fill_access_byte_32(sh_bool present,sh_uint8 dpl,sh_bool descriptor_type,sh_uint8 segment_type) { + sh_uint8 access=0; + access|=(present?1:0)<<7; + access|=(dpl&0x3)<<5; + access|=(descriptor_type?1:0)<<4; + access|=(segment_type&0xF); + return access; +} +// Generate granularity byte +inline sh_uint8 sh_gdt_fill_granularity_byte_32(sh_bool granularity,sh_bool db,sh_bool l,sh_bool avl) { + sh_uint8 g=0; + g|=(granularity?1:0)<<7; + g|=(db?1:0)<<6; + g|=(l?1:0)<<5; + g|=(avl?1:0)<<4; + return g; +} +// Fill GDT entry 32 bits, expect granularity as sh_gdt_fill_granularity_byte_32 would return it +sh_gdt_GDT_ENTRY_32 sh_gdt_fill_gdt_entry_32(sh_uint32 limit,sh_uint32 base,sh_uint8 access,sh_uint8 granularity); +// Fill GDT 32 bits +SH_STATUS sh_gdt_fill_gdt_32(sh_gdt_GDT_32 *gdt_32); +#endif diff --git a/shelter/lib/include/irq/gsi.h b/shelter/lib/include/irq/gsi.h new file mode 100644 index 0000000..17dad13 --- /dev/null +++ b/shelter/lib/include/irq/gsi.h @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_GSI_H +#define SH_LIB_GSI_H +#include "std/stdlib.h" +#include "devs/apic/ioapic.h" +// GSI polarity enum +enum sh_gsi_POLARITY { + SH_GSI_POLARITY_NOT_SET=0, + SH_GSI_POLARITY_BUS_DEFAULT, + SH_GSI_POLARITY_ACTIVE_HIGH, + SH_GSI_POLARITY_ACTIVE_LOW +}; +// GSI trigger mode enum +enum sh_gsi_TRIGGER_MODE { + SH_GSI_TRIGGER_MODE_NOT_SET=0, + SH_GSI_TRIGGER_MODE_BUS_DEFAULT, + SH_GSI_TRIGGER_MODE_EDGE, + SH_GSI_TRIGGER_MODE_LEVEL +}; +// Interrupt source override (ISO) structure +typedef struct { + sh_uint32 gsi; + // must default to SH_FALSE + sh_bool valid; + // when ISOs array is initialized, this field must default to 0 + sh_uint8 source_irq; + // these two fields are determined by the flags field in the MADT entry. Bus-default value are resolved when writing IOREDTBL + enum sh_gsi_POLARITY polarity; + enum sh_gsi_TRIGGER_MODE trigger_mode; + // when ISOs array is initialized, this field must default to 0 + sh_uint8 bus; +} sh_gsi_ISO; +// Initialize a 256 elements array of sh_gsi_ISO structs +SH_STATUS sh_gsi_iso_array_init(); +// Register an ISO, this function is supposed to be used during MADT parsing when encountering an ISO. It expect the field as they are provided into the MADT entry +SH_STATUS sh_gsi_iso_register(sh_uint8 bus,sh_uint8 source,sh_uint32 gsi,sh_uint16 flags); +// Return an ISO structure for the given interrupt +sh_gsi_ISO *sh_gsi_get_iso_by_irq(sh_uint8 irq); +// Return an ISO structure for the given GSI +sh_gsi_ISO *sh_gsi_get_iso_by_gsi(sh_uint32 gsi); +// These two functions provide a thread-safe and "interrupt-storm" safe way to get and set IOREDTBL entries +// Read the IOREDTBL entry associated with the provided GSI +SH_STATUS sh_gsi_get(sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry); +// Set the provided GSI to the corresponding IOREDTBL entry, mask the IOOREDTBL entry and doesn't unmask it +SH_STATUS sh_gsi_set(sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry); +// Set the provided IRQ to IOREDTBL entry, calculate the expected GSI using sh_gsi_get_iso_by_irq +SH_STATUS sh_gsi_irq_set(sh_uint8 irq,sh_ioapic_IOREDTBL_ENTRY *entry); +// Mask the IOREDTBL entry corresponding to the provided GSI +inline SH_STATUS sh_gsi_mask(sh_uint32 gsi) { + return sh_ioapic_mask_gsi(sh_ioapic_get_dev_by_gsi(gsi),gsi); +} +// Unmask the IOREDTBL entry corresponding to the provided GSI +inline SH_STATUS sh_gsi_unmask(sh_uint32 gsi) { + return sh_ioapic_unmask_gsi(sh_ioapic_get_dev_by_gsi(gsi),gsi); +} +// Mask the IOREDTBL entry corresponding to the provided IRQ +SH_STATUS sh_gsi_irq_mask(sh_uint8 irq); +// Unmask the IOREDTBL entry corresponding to the provided IRQ +SH_STATUS sh_gsi_irq_unmask(sh_uint8 irq); +// Load all legacy IRQ to IOREDTBL entries, intented to be called only one time +SH_STATUS sh_gsi_irq_switch(); +#endif diff --git a/shelter/lib/include/irq/idt.h b/shelter/lib/include/irq/idt.h new file mode 100644 index 0000000..aa1e6a0 --- /dev/null +++ b/shelter/lib/include/irq/idt.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_IDT_H +#define SH_LIB_IDT_H +#include "std/status.h" +#include "std/type.h" +// IDT entry structure +#pragma pack(1) +typedef struct { + sh_uint16 offset_low; + sh_uint16 selector; + sh_uint8 ist; + sh_uint8 type_attr; + sh_uint16 offset_mid; + sh_uint32 offset_high; + sh_uint32 reserved; +} sh_idt_IDT_ENTRY; +#pragma pack() +// IDTR structure +#pragma pack(1) +typedef struct { + sh_uint16 limit; + sh_uint64 base; +} sh_idt_IDTR; +#pragma pack() +// Full IDT structure +#pragma pack(1) +typedef struct { + sh_idt_IDT_ENTRY entries[256]; +} sh_idt_IDT; +#pragma pack() +// Generate type_attr byte +inline sh_uint8 sh_idt_fill_type_attr_byte(sh_bool present,sh_uint8 dpl,sh_uint8 type) { + return ((present?1:0)<<7)|((dpl&0x3)<<5)|(type&0x1F); +} +// Fill an IDT entry, expect type_attr as sh_idt_fill_type_attr_byte would return it +sh_idt_IDT_ENTRY sh_idt_fill_idt_entry(sh_uint64 offset,sh_uint16 selector,sh_uint8 ist,sh_uint8 type_attr); +// Fill the IDT +SH_STATUS sh_idt_fill_idt(sh_idt_IDT *idt); +// Fill and load IDTR +SH_STATUS sh_idt_load_idtr(sh_idt_IDT *idt); +#endif diff --git a/shelter/lib/include/irq/irq.h b/shelter/lib/include/irq/irq.h new file mode 100644 index 0000000..0a105b7 --- /dev/null +++ b/shelter/lib/include/irq/irq.h @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_IRQ_H +#define SH_LIB_IRQ_H +#include "std/stdlib.h" +// Interrupt frame structure +#pragma pack(1) +typedef struct { + sh_uint64 r11,r10,r9,r8,rdx,rcx,rax; + sh_uint64 vector; + sh_uint64 error_code; + sh_uint64 rip; + sh_uint64 cs; + sh_uint64 rflags; +} sh_irq_INTERRUPT_FRAME; +#pragma pack() +#define SH_IRQ_DIV_BY_ZERO_FAULT_STRING "Division by Zero #DE" +#define SH_IRQ_DEBUG_STRING "Debug #DB\nWarning: Usage of debugger in Shelter isn't supported and any #DB fault will result in a dead kernel." +#define SH_IRQ_PAGE_FAULT_STRING "Page fault #PF" +#define SH_IRQ_NMI_FAULT_STRING "Non maskable interrupt" +#define SH_IRQ_BREAKPOINT_STRING "Breakpoint #BP\nWarning: Usage of debugger in Shelter isn't supported but usage of #BP fault will not block the kernel." +#define SH_IRQ_OVERFLOW_STRING "Overflow #OF" +#define SH_IRQ_BOUND_RANGE_STRING "Bound range Exceedeed #BR" +#define SH_IRQ_INVALID_OPCODE_STRING "Invalid Opcode #UD" +#define SH_IRQ_DEVICE_NOT_AVAILABLE_STRING "Device Not Available #NM" +#define SH_IRQ_DOUBLE_FAULT_STRING "Double Fault #DF" +#define SH_IRQ_COPROCESSOR_SEGMENT_OVRERRUN_STRING "Coprocessor segment overrun" +#define SH_IRQ_INVALID_TSS_STRING "Invalid TSS #TS" +#define SH_IRQ_SEGMENT_NOT_PRESENT_STRING "Segment Not Present #NP" +#define SH_IRQ_STACK_SEGMENT_FAULT_STRING "Stack Segment Fault #SS" +#define SH_IRQ_GENERAL_PROTECTION_FAULT_STRING "General Protection Fault #GP" +#define SH_IRQ_X87_FLOATING_POINT_EXCEPTION_STRING "x87 Floating Point Exception #MF" +#define SH_IRQ_ALIGNMENT_CHECK_STRING "Alignment Check #AC" +#define SH_IRQ_MACHINE_CHECK_STRING "Machine Check #MC" +#define SH_IRQ_SIMD_FLOATING_POINT_EXCEPTION_STRING "SIMD Floating Point Exception #XM" +#define SH_IRQ_VIRTUALIZATION_EXCEPTION_STRING "Virtualization Exception #VE" +#define SH_IRQ_CONTROL_PROTECTION_EXCEPTION_STRING "Control Protection Exception #CP" +#define SH_IRQ_HYPERVISOR_INJECTION_EXCEPTION_STRING "Hypervisor Injection Exception #HV\nWarning: Shelter will never communicate with an hypervisor." +#define SH_IRQ_VMM_COMMUNICATION_EXCEPTION_STRING "VMM Communication Exception #VC\nWarning: Shelter will never communicate with an hypervisor." +#define SH_IRQ_SECURITY_EXCEPTION_STRING "Security Exception #SX\nWarning: Shelter will never communicate with an hypervisor." +typedef void (*sh_irq_HANDLER_PTR)(); +// Start TSC calibration +void sh_irq_start_tsc(); +// Return TSC delta mesured between two PIC interrupts +sh_uint64 sh_irq_get_tsc_delta(); +// Set timer state of this CPU to SH_TRUE +void sh_irq_start_timer(); +// Get timer state of this CPU +sh_bool sh_irq_get_timer_state(); +// Set the irq_managed_by_ioapic to SH_TRUE +SH_STATUS sh_irq_switch_irq_management(); +// Register a legacy IRQ handler, unmask the corresponding GSI +SH_STATUS sh_irq_legacy_register_handler(sh_uint8 legacy_irq,sh_irq_HANDLER_PTR handler); +// Present interrupt frame if it's a fault +void sh_irq_present_frame(sh_irq_INTERRUPT_FRAME *frame); +// Dispatch interrupts +void sh_irq_dispatch(sh_irq_INTERRUPT_FRAME *frame); +#endif diff --git a/shelter/lib/include/irq/tss.h b/shelter/lib/include/irq/tss.h new file mode 100644 index 0000000..2316891 --- /dev/null +++ b/shelter/lib/include/irq/tss.h @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_TSS_H +#define SH_LIB_TSS_H +#include "std/status.h" +#include "std/type.h" +#include "std/malloc.h" +#include "std/mem.h" +// TSS structure +#pragma pack(1) +typedef struct { + sh_uint32 reserved0; + sh_uint64 rsp0; + sh_uint64 rsp1; + sh_uint64 rsp2; + sh_uint64 reserved1; + sh_uint64 ist1; + sh_uint64 ist2; + sh_uint64 ist3; + sh_uint64 ist4; + sh_uint64 ist5; + sh_uint64 ist6; + sh_uint64 ist7; + sh_uint64 reserved2; + sh_uint16 reserved3; + sh_uint16 iomap_base; +} sh_tss_TSS; +#pragma pack() +// TR structure +#pragma pack(1) +typedef struct { + sh_uint16 limit; + sh_uint64 base; +} sh_tss_TR; +#pragma pack() +// Fill TSS structure for any CPU core and allocate stacks +SH_STATUS sh_tss_fill_tss(sh_tss_TSS *tss); +// Fill and load TR +SH_STATUS sh_tss_load_tr(sh_tss_TSS *tss); +#endif diff --git a/shelter/lib/include/kernel/conf.h b/shelter/lib/include/kernel/conf.h index 5757bf4..4064e19 100644 --- a/shelter/lib/include/kernel/conf.h +++ b/shelter/lib/include/kernel/conf.h @@ -5,7 +5,22 @@ #include "std/status.h" #include "memory/page.h" #include "memory/vmem_layout.h" +#include "devs/devs.h" #define SH_CONF_BOOT_CONFIG_VA SH_VMEM_LAYOUT_BOOT_CONFIG_VA +// Framebuffer configuration +typedef struct __attribute__((aligned(8))) { + sh_bool fb_present; + sh_page_VIRTUAL_ADDRESS fb_pa; + sh_uint32 white_pixel_value; + sh_uint32 gray_pixel_value; + sh_uint64 size_in_bytes; + sh_uint32 fb_height; + sh_uint32 fb_width; + sh_uint16 text_x; + sh_uint16 text_y; + sh_uint16 text_width; + sh_uint16 text_height; +} sh_conf_FB_CONFIG; // Boot config structure. typedef struct __attribute__((aligned(8))) { sh_uint8 sig_start[8]; @@ -18,8 +33,14 @@ typedef struct __attribute__((aligned(8))) { sh_bool log_disable_serial_port; sh_bool disable_serial_port; sh_uint16 log_ring_size; + sh_uint64 acpi_rsdp; + sh_uint8 acpi_ver; + sh_uint16 kbd_events_queue_capacity; + sh_conf_FB_CONFIG fb_config; sh_uint8 sig_end[8]; } sh_conf_BOOT_CONFIG; // Check and create boot config structure. SH_STATUS sh_conf_get_boot_config(sh_conf_BOOT_CONFIG **config); +// Parse a configuration DevS query +SH_STATUS sh_conf_devs_query(char *sub_path,sh_devs_RESULT *result); #endif diff --git a/shelter/lib/include/kernel/efifb.h b/shelter/lib/include/kernel/efifb.h new file mode 100644 index 0000000..fe63595 --- /dev/null +++ b/shelter/lib/include/kernel/efifb.h @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_EFIFB_H +#define SH_LIB_EFIFB_H +#include "std/stdlib.h" +#include "kernel/conf.h" +// Initialize the EFI FB subsystem +SH_STATUS sh_efifb_init_fb(sh_conf_FB_CONFIG *fb_conf,sh_page_PAGE_TABLE_POOL *ptp); +// Initialize the boot progress bar +SH_STATUS sh_efifb_init_bar(); +// Set the progress bar to a certain percentage +SH_STATUS sh_efifb_set_bar(sh_uint8 percent); +#endif diff --git a/shelter/lib/include/kernel/log.h b/shelter/lib/include/kernel/log.h index 5755dae..a2944ab 100644 --- a/shelter/lib/include/kernel/log.h +++ b/shelter/lib/include/kernel/log.h @@ -12,6 +12,7 @@ typedef sh_uint8 sh_log_OUTPUT_TYPE; #define SH_LOG_CRITICAL ((sh_log_OUTPUT_TYPE)4) #define SH_LOG_FATAL ((sh_log_OUTPUT_TYPE)5) #define SH_LOG_TEST ((sh_log_OUTPUT_TYPE)6) +#define SH_LOG_FAULT ((sh_log_OUTPUT_TYPE)7) typedef sh_uint16 sh_log_OUTPUT_SOURCE; #define SH_LOG_SOURCE_MAIN ((sh_log_OUTPUT_SOURCE)0) #define SH_LOG_SOURCE_CONF ((sh_log_OUTPUT_SOURCE)1) @@ -22,6 +23,11 @@ typedef sh_uint16 sh_log_OUTPUT_SOURCE; #define SH_LOG_SOURCE_PBA ((sh_log_OUTPUT_SOURCE)6) #define SH_LOG_SOURCE_HEAP ((sh_log_OUTPUT_SOURCE)7) #define SH_LOG_SOURCE_STD ((sh_log_OUTPUT_SOURCE)8) +#define SH_LOG_SOURCE_MEMS ((sh_log_OUTPUT_SOURCE)9) +#define SH_LOG_SOURCE_CPUF ((sh_log_OUTPUT_SOURCE)10) +#define SH_LOG_SOURCE_ACPI ((sh_log_OUTPUT_SOURCE)11) +#define SH_LOG_SOURCE_TSC ((sh_log_OUTPUT_SOURCE)12) +#define SH_LOG_SOURCE_SMP ((sh_log_OUTPUT_SOURCE)13) typedef struct { sh_log_OUTPUT_TYPE output_type; sh_log_OUTPUT_SOURCE output_source; @@ -30,11 +36,11 @@ typedef struct { } sh_log_OUTPUT_PAYLOAD; // Return SH_TRUE if provided output type is valid. static inline sh_bool sh_log_output_type_valid(sh_log_OUTPUT_TYPE t) { - return t<=SH_LOG_TEST; + return t<=SH_LOG_FAULT; } // Return SH_TRUE if provided source type is valid. static inline sh_bool sh_log_output_source_valid(sh_log_OUTPUT_SOURCE s) { - return s<=SH_LOG_SOURCE_STD; + return s<=SH_LOG_SOURCE_SMP; } // Load serial logging setting void sh_log_load_serial_setting(sh_bool is_disabled); @@ -46,6 +52,8 @@ void sh_log_load_logging_ring_size(sh_uint16 pages_count); sh_uint32 sh_log_get_logging_ring_size(); // Return total bytes written to the ring buffer sh_uint64 sh_log_get_total_bytes_written(); +// Disable global logging ring, should only be used after SMP is enabled +void sh_log_disable_global_logging_ring(); // Log a byte void sh_log_byte(sh_uint8 byte); // Log a string @@ -103,6 +111,8 @@ SH_STATUS sh_log_error(const char* str,sh_log_OUTPUT_SOURCE source); SH_STATUS sh_log_critical(const char* str,sh_log_OUTPUT_SOURCE source); // Print a string to fatal channel, from provided source. SH_STATUS sh_log_fatal(const char* str,sh_log_OUTPUT_SOURCE source); +// Print a string to fault channel, from provided source. +SH_STATUS sh_log_fault(const char* str,sh_log_OUTPUT_SOURCE source); // Print a string to test channel. Doesn't include the new line caracter. SH_STATUS sh_log_ltest(const char* str); // Print a string to debug channel, from provided source. Doesn't include the new line caracter. @@ -117,6 +127,8 @@ SH_STATUS sh_log_lerror(const char* str,sh_log_OUTPUT_SOURCE source); SH_STATUS sh_log_lcritical(const char* str,sh_log_OUTPUT_SOURCE source); // Print a string to fatal channel, from provided source. Doesn't include the new line caracter. SH_STATUS sh_log_lfatal(const char* str,sh_log_OUTPUT_SOURCE source); +// Print a string to fault channel, from provided source. Doesn't include the new line caracter. +SH_STATUS sh_log_lfault(const char* str,sh_log_OUTPUT_SOURCE source); // The following functions format the output before logging it. The syntax is as follow: // - %s : char* // - %d : double @@ -141,6 +153,8 @@ SH_STATUS sh_log_ferror(const sh_log_OUTPUT_SOURCE source,const char* format,... SH_STATUS sh_log_fcritical(const sh_log_OUTPUT_SOURCE source,const char* format,...); // Print a string to fatal channel, from provided source. Format it before hand SH_STATUS sh_log_ffatal(const sh_log_OUTPUT_SOURCE source,const char* format,...); +// Print a string to fault channel, from provided source. Format it before hand +SH_STATUS sh_log_ffault(const sh_log_OUTPUT_SOURCE source,const char* format,...); // Print every information about memory statictics. Require log level to be 1 or 0 SH_STATUS sh_log_mem_stats(sh_log_OUTPUT_SOURCE source); #endif diff --git a/shelter/lib/include/kernel/test.h b/shelter/lib/include/kernel/test.h index 50a8253..a509e3e 100644 --- a/shelter/lib/include/kernel/test.h +++ b/shelter/lib/include/kernel/test.h @@ -4,4 +4,5 @@ #include "kernel/tests/test_radix.h" #include "kernel/tests/test_pez.h" #include "kernel/tests/test_malloc.h" +#include "kernel/tests/test_queues.h" #include "kernel/tests/test_utils.h" diff --git a/shelter/lib/include/kernel/tests/payloads/test_malloc_payload.h b/shelter/lib/include/kernel/tests/payloads/test_malloc_payload.h new file mode 100644 index 0000000..e213b49 --- /dev/null +++ b/shelter/lib/include/kernel/tests/payloads/test_malloc_payload.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MPL-2.0 +// This file contain the values to use as alloc size for the benchmark of sh_malloc and sh_free +// It's autogenerated by tools/generator/malloc_payload_gen.py +// Copy the output of this script in this file to regenerate it. +#ifndef SH_LIB_PAYLOADS_TEST_MALLOC +#define SH_LIB_PAYLOADS_TEST_MALLOC +#include "std/type.h" +__attribute__((section(".data"))) sh_uint32 test_malloc_small_size[10000]={126,43,4,658,272,58,83,65,50,93,429,111,178,82,173,76,24,501,258,91,186,82,456,24,148,155,424,235,339,429,1017,153,18,15,40,328,6,326,46,59,161,15,507,192,69,166,108,239,60,167,98,56,177,175,68,217,148,252,43,112,417,68,25,117,320,176,6,32,35,71,206,112,13,737,119,74,5,51,523,87,15,77,100,378,224,260,192,39,467,150,325,3,132,267,34,310,119,525,454,322,12,50,23,86,65,252,48,182,154,14,37,86,68,194,71,66,44,40,28,184,232,239,13,189,31,145,7,263,53,222,162,25,269,89,140,305,9,71,526,53,78,138,781,5,25,473,202,60,78,160,124,176,292,46,104,49,234,210,221,24,64,469,138,230,171,6,25,267,216,3,251,54,242,171,85,365,49,34,45,226,103,419,10,47,54,647,684,200,148,116,397,68,563,274,267,305,81,168,84,57,69,86,88,40,321,15,46,28,12,226,217,305,79,181,589,200,243,296,33,119,612,218,162,19,485,4,19,165,351,352,219,225,29,123,107,321,284,77,418,159,31,215,260,313,154,120,76,74,193,634,24,69,65,77,252,83,214,316,14,186,373,201,213,5,97,113,62,163,8,310,117,95,143,145,26,18,17,34,10,64,48,37,55,95,551,29,25,19,60,64,136,149,132,474,84,446,16,55,4,278,5,45,170,237,138,154,391,104,33,262,31,3,466,48,429,181,42,112,130,438,3,223,143,326,519,18,639,16,78,190,72,611,21,790,122,125,170,106,130,275,189,437,92,10,336,23,167,38,210,117,108,335,821,89,266,24,248,278,24,20,262,227,158,4,7,53,30,391,15,219,186,393,211,469,19,365,45,57,6,402,114,222,57,44,438,96,64,125,346,5,282,24,27,43,98,126,78,143,17,152,255,321,233,82,235,79,354,152,273,496,645,16,175,136,595,750,21,51,54,327,99,17,405,74,190,34,140,22,118,13,150,159,4,17,12,90,417,26,60,211,25,125,315,101,144,5,7,190,26,16,617,59,191,59,229,71,117,22,69,260,97,341,67,76,5,113,568,498,106,97,82,272,95,440,39,211,29,2,186,78,132,148,118,186,354,387,85,124,90,94,182,93,83,231,113,379,27,343,11,150,49,199,29,358,36,107,254,10,21,310,27,3,89,70,320,153,67,312,96,22,89,13,3,158,137,69,445,123,30,62,118,269,384,404,79,271,169,57,7,236,487,56,227,135,28,183,14,227,51,22,166,491,22,57,108,41,98,120,5,42,71,271,150,222,46,71,163,278,6,2,327,109,116,358,237,366,200,384,74,179,345,205,235,285,183,351,124,490,29,26,203,3,3,22,12,20,19,192,46,239,131,180,49,7,341,34,198,15,263,184,93,590,30,102,121,2,396,92,544,50,369,68,79,491,460,422,169,138,79,331,169,91,92,69,12,37,494,116,145,507,281,46,256,59,36,410,40,150,30,228,158,49,70,62,129,129,68,29,125,18,382,125,35,316,415,114,130,39,125,39,56,63,438,72,103,205,30,384,415,175,24,237,250,8,17,202,447,226,292,225,12,129,53,4,160,37,792,236,370,154,124,2,270,226,76,112,176,288,144,108,27,263,502,11,194,317,253,188,134,310,155,3,63,7,875,11,94,48,10,59,225,108,56,62,86,247,92,284,175,54,71,130,121,10,23,29,81,224,112,118,253,148,161,215,276,121,242,77,146,373,558,65,61,511,96,327,102,261,164,24,127,38,21,302,405,151,34,164,46,30,3,24,49,52,96,9,102,223,342,297,106,41,91,11,308,105,254,108,54,194,87,221,198,53,124,17,313,18,40,142,201,485,45,128,96,230,643,251,232,530,14,47,211,90,289,45,128,186,428,39,18,151,70,164,965,12,117,55,174,34,424,173,54,173,57,214,320,571,140,333,42,20,180,415,92,73,483,46,55,652,50,141,172,174,48,83,110,90,354,11,265,282,68,41,378,2,133,256,130,351,235,88,228,70,83,85,475,77,66,14,8,21,205,133,43,221,99,102,97,317,11,32,34,142,132,380,115,185,177,94,368,137,78,81,117,23,13,41,37,193,110,357,180,88,3,434,183,300,220,47,142,205,173,200,14,155,54,101,150,179,5,721,190,75,126,253,40,478,49,62,221,267,33,282,61,64,6,38,410,63,67,121,51,27,315,98,41,95,302,181,24,429,53,450,11,13,13,20,800,10,266,385,448,78,391,250,117,207,72,69,45,70,73,79,11,22,182,89,417,97,276,113,168,105,151,653,44,346,602,19,444,14,505,37,22,99,628,138,690,39,456,210,134,87,21,4,236,384,5,143,219,25,93,291,341,271,441,33,24,361,411,64,152,126,366,2,9,44,47,570,36,288,127,35,170,84,983,15,37,56,310,631,397,7,154,284,223,51,339,5,586,15,613,103,141,53,18,252,16,83,149,52,516,39,2,342,71,186,135,717,168,501,142,93,279,229,308,246,600,203,65,50,225,252,179,267,84,119,266,16,73,213,95,352,423,554,132,4,300,87,156,42,66,75,204,189,24,31,20,141,144,498,387,31,280,48,60,176,516,100,137,823,104,31,213,127,16,176,118,153,106,64,10,84,210,39,290,116,218,69,345,463,10,352,251,8,290,537,245,54,504,51,10,637,2,3,148,150,576,253,104,173,200,511,50,137,31,18,127,81,52,117,303,440,45,45,36,183,25,10,470,46,172,176,159,127,138,43,150,251,126,299,95,22,2,157,63,2,83,365,730,178,450,34,149,10,158,390,44,9,335,264,8,174,248,363,11,261,209,141,36,262,28,179,304,34,115,232,425,297,114,36,48,19,3,127,564,132,66,219,16,5,22,7,5,23,177,176,539,235,78,122,16,59,162,207,470,169,23,289,25,100,126,41,60,40,128,202,315,90,50,9,48,163,52,127,22,385,11,83,104,33,398,342,422,56,38,511,27,152,116,83,12,183,212,219,427,238,190,120,106,22,158,881,378,478,54,24,187,75,96,80,342,765,129,7,14,251,41,380,773,84,88,5,102,124,62,22,111,159,127,774,353,364,128,308,266,188,8,2,130,284,154,188,95,796,42,90,71,68,95,122,108,6,201,28,95,59,252,339,63,289,316,83,355,97,5,8,45,259,33,148,39,4,16,155,50,99,8,465,21,163,31,93,62,178,12,563,252,161,32,329,24,276,120,113,107,142,446,213,99,10,249,81,19,421,12,243,171,168,127,32,351,132,39,356,471,137,153,543,172,122,349,250,279,19,218,219,221,898,45,82,149,20,159,233,36,53,324,105,676,515,420,65,585,317,19,38,139,38,68,75,30,212,259,247,72,57,210,288,92,21,170,210,170,77,20,212,256,114,58,32,290,464,78,25,26,120,58,57,90,257,9,97,29,108,14,25,81,76,665,80,143,179,32,5,516,634,602,9,169,45,208,72,6,10,261,417,174,48,32,20,92,224,119,21,369,66,105,118,65,61,389,139,156,158,29,6,59,175,376,72,387,175,352,77,6,105,62,128,148,243,47,64,133,64,79,66,236,15,183,175,268,143,135,117,19,61,54,5,74,152,213,288,569,324,55,149,214,290,24,52,83,128,387,104,170,209,654,30,384,123,14,130,68,180,11,760,77,82,185,169,167,288,31,112,143,569,36,11,83,460,60,226,200,513,8,101,723,782,279,177,100,5,89,302,179,26,132,38,201,350,121,40,37,54,187,36,165,42,85,60,349,82,58,50,322,99,70,110,14,136,36,70,202,186,381,85,847,71,12,76,137,610,388,206,178,13,268,134,14,382,46,181,89,227,326,174,22,122,228,79,272,130,10,539,40,134,295,256,10,373,125,50,35,158,37,110,46,104,217,143,209,73,72,218,326,13,84,109,16,66,117,22,499,478,80,25,77,88,207,113,219,39,24,114,275,205,129,203,180,99,70,43,92,17,44,18,644,71,27,129,5,164,76,67,289,444,202,57,322,58,39,19,94,235,311,60,193,42,35,31,689,187,23,292,91,43,110,166,36,46,215,44,316,451,173,89,43,91,38,434,150,261,11,36,83,483,15,106,666,227,27,15,125,154,205,789,91,210,398,28,145,328,11,176,4,55,36,39,366,75,63,94,296,407,156,382,35,537,312,360,148,514,356,223,25,135,604,97,89,67,10,55,181,103,116,133,350,87,6,492,130,131,226,185,207,259,188,22,266,27,341,184,468,319,65,3,188,115,320,167,83,54,101,27,101,84,4,21,70,196,167,132,327,7,39,130,148,71,12,116,5,83,28,97,130,14,433,324,150,56,209,93,76,28,69,13,187,171,30,132,214,141,56,95,452,509,44,137,127,40,5,105,24,195,31,188,150,96,105,112,38,14,92,15,178,98,28,655,132,24,273,139,115,164,38,376,35,16,239,127,8,35,140,27,26,49,30,294,196,266,27,271,169,213,195,267,144,63,104,28,32,68,266,324,160,105,85,130,43,358,168,393,42,241,111,63,61,217,45,273,10,377,212,34,54,226,28,106,217,210,51,47,184,104,11,56,156,69,232,256,238,23,54,298,141,22,7,27,461,75,27,221,52,218,99,52,244,24,147,37,263,46,82,126,64,645,224,91,24,113,193,377,191,21,152,104,237,260,27,179,6,251,133,206,115,2,153,243,309,295,141,13,9,205,889,332,67,116,390,150,121,146,70,50,22,7,42,118,205,96,141,133,186,93,30,34,69,264,84,26,96,262,104,163,375,27,126,185,54,541,188,108,618,147,9,260,52,191,103,86,384,379,120,113,386,102,312,197,136,29,154,129,162,129,21,368,199,307,16,371,251,228,275,61,94,335,49,28,65,73,164,7,349,165,186,136,32,122,151,32,95,196,93,18,503,355,6,142,169,307,36,114,94,12,114,93,151,135,271,99,70,289,205,84,67,75,578,26,75,413,34,35,195,17,21,40,77,34,37,51,136,68,233,30,238,14,257,74,423,56,193,64,169,190,251,106,63,360,112,38,42,38,241,8,193,37,154,61,79,24,619,249,16,552,153,53,9,773,11,22,206,427,11,12,127,204,144,245,79,29,187,164,426,7,153,175,73,25,30,87,3,393,94,125,246,123,35,128,124,64,809,235,170,7,315,107,34,205,160,53,45,93,127,90,19,8,134,564,604,11,125,36,318,130,351,84,80,228,317,142,56,197,202,3,40,165,330,102,34,434,184,189,57,327,113,51,231,344,79,81,50,81,337,423,10,427,155,116,446,512,483,202,17,78,158,69,69,16,558,66,60,211,33,65,98,655,83,78,44,5,273,8,189,126,216,23,151,120,56,4,148,125,45,36,37,56,41,165,198,64,756,193,130,78,543,449,33,44,64,2,48,27,62,4,26,280,304,66,241,156,111,154,145,206,2,22,106,22,630,23,178,615,75,124,243,55,76,23,233,526,273,15,85,33,340,142,256,296,64,407,257,544,4,342,80,277,77,67,156,7,129,471,32,261,232,329,141,65,34,114,178,138,109,123,201,193,122,50,197,425,206,36,450,158,205,266,45,115,73,36,165,131,3,199,30,284,15,145,222,57,291,321,131,49,65,5,178,55,214,92,144,243,351,131,440,191,11,14,27,312,126,63,207,83,109,16,140,54,131,3,496,231,82,263,89,47,28,212,210,168,8,2,266,14,67,82,58,362,31,72,26,89,24,172,26,59,49,106,192,126,280,87,297,33,444,241,140,175,15,207,21,41,208,664,115,57,475,146,149,155,141,120,200,3,17,156,84,287,83,150,5,22,49,31,9,277,250,78,57,612,17,199,148,232,18,291,4,34,110,159,43,329,49,95,104,373,138,291,74,60,123,278,8,388,23,221,63,318,372,39,15,188,30,54,74,102,85,19,499,277,92,109,335,127,140,284,105,52,234,125,110,27,24,78,86,476,23,44,27,110,2,91,542,422,141,21,7,411,51,3,29,86,208,35,159,103,299,159,97,5,21,141,24,315,26,455,139,34,162,10,355,165,461,276,36,226,48,139,97,98,406,204,292,292,421,120,156,28,577,168,195,158,328,151,206,66,123,59,208,399,97,3,27,154,104,147,68,220,52,157,78,115,66,350,339,97,140,55,279,156,12,49,33,14,170,122,24,33,3,47,48,416,186,72,20,71,117,125,56,117,57,42,138,137,53,722,57,39,39,404,38,275,130,182,344,58,114,359,5,414,21,147,47,155,212,105,18,332,4,11,127,193,68,42,20,5,79,48,17,224,89,564,638,93,150,120,115,239,10,109,110,88,109,105,43,79,21,23,443,98,20,207,594,56,383,671,68,350,274,48,154,73,204,3,46,12,202,92,476,54,310,338,65,214,12,63,151,147,47,39,52,36,461,80,28,64,146,337,24,261,80,203,518,34,105,150,149,64,287,262,55,317,498,493,379,174,168,25,118,132,29,24,449,61,18,39,611,338,83,53,313,166,91,9,175,99,180,220,165,218,304,312,282,105,108,77,301,144,38,241,30,93,163,172,769,92,97,362,94,395,102,162,76,495,164,50,263,36,188,131,111,268,43,221,273,58,229,133,148,321,119,55,17,69,220,22,112,90,19,19,3,157,50,26,84,101,148,140,378,28,21,12,96,206,32,233,195,183,172,36,32,109,353,19,111,82,91,96,283,10,28,196,152,219,275,6,256,172,104,420,123,338,38,18,10,353,105,19,552,56,615,2,208,219,135,881,44,53,65,59,87,18,129,32,29,42,111,129,19,351,71,151,164,77,113,326,180,190,38,4,22,20,34,304,156,41,66,162,128,105,35,322,232,210,61,26,32,48,197,12,23,11,235,19,188,59,436,40,107,368,273,248,33,291,156,16,83,684,80,139,170,199,183,144,111,107,250,461,147,188,53,134,194,29,148,112,13,89,49,36,255,91,33,516,133,159,158,550,152,30,513,35,372,764,70,39,78,67,170,119,421,268,9,2,131,8,145,4,4,231,24,577,12,11,322,94,60,25,61,288,380,199,24,55,140,92,19,99,43,279,146,379,13,678,29,670,270,68,76,154,42,66,71,465,3,20,66,235,46,30,149,80,82,239,62,12,183,71,11,88,51,50,120,16,2,16,97,201,53,222,699,53,87,34,69,371,3,57,208,127,84,16,58,76,66,75,7,319,281,30,74,53,261,362,12,438,251,203,316,522,5,618,2,89,85,26,97,194,366,55,299,372,54,410,526,206,41,180,66,79,141,145,36,248,130,300,134,10,104,428,74,312,6,27,225,502,124,27,190,156,57,117,128,101,67,220,205,238,79,313,109,236,192,136,191,173,29,132,101,92,143,94,391,60,217,70,94,393,171,57,338,6,457,3,167,243,22,85,106,78,93,66,274,137,108,38,62,117,285,54,180,229,122,38,299,171,558,101,58,78,63,37,318,181,4,5,244,259,41,20,173,96,188,388,306,224,36,445,39,220,277,50,51,34,353,130,233,8,135,217,36,351,228,124,170,132,233,158,62,15,306,514,136,11,206,44,27,76,180,166,170,49,241,117,28,332,90,33,214,20,43,19,177,42,355,10,405,175,395,86,30,297,103,3,150,606,14,114,728,124,131,15,131,27,318,327,175,576,23,26,263,58,5,41,55,50,242,81,45,93,134,14,7,208,53,48,129,19,30,262,34,137,73,186,200,44,28,122,114,345,76,100,22,201,54,278,54,234,84,515,76,5,254,123,186,162,257,181,46,49,135,46,126,195,100,101,188,17,74,207,35,188,413,105,114,215,226,33,268,7,146,53,69,15,120,229,122,3,2,45,152,165,30,102,328,322,37,46,25,21,372,161,10,93,43,84,139,88,521,259,16,809,135,11,132,11,29,170,305,3,698,41,6,90,297,14,215,110,26,162,354,177,34,14,77,110,143,76,203,97,27,147,89,17,177,213,182,259,178,133,106,156,245,39,160,153,309,85,72,192,72,166,285,85,425,593,93,402,314,132,780,200,154,188,173,251,234,11,6,29,500,5,102,78,300,213,269,20,62,128,10,15,403,173,45,36,416,75,308,312,89,19,104,196,166,56,315,485,421,164,120,42,146,22,246,155,115,30,37,267,691,138,149,63,85,7,202,248,314,53,311,262,184,127,186,410,545,126,12,160,6,63,69,165,261,459,154,98,556,221,36,42,98,46,65,115,126,139,21,168,195,97,409,38,78,77,489,525,78,276,109,78,293,145,59,128,193,32,116,542,272,17,17,16,246,36,21,55,68,511,194,338,198,23,190,291,115,183,637,95,104,728,449,123,74,52,220,28,567,96,403,110,253,145,213,118,149,46,60,43,123,111,431,214,52,33,298,69,22,3,30,54,107,24,17,75,136,416,116,58,519,22,93,5,8,404,288,174,119,93,9,260,3,79,35,5,273,238,607,69,6,174,418,136,264,38,682,13,2,25,173,146,510,47,59,67,55,77,9,281,260,92,59,149,43,268,515,192,59,268,44,277,332,347,35,557,187,72,365,49,36,595,382,13,270,119,58,253,74,294,96,139,65,131,233,368,75,378,209,174,670,174,43,47,73,403,334,127,93,706,101,120,99,49,289,27,264,74,419,183,232,400,214,300,109,56,473,333,372,92,303,120,89,690,3,267,108,28,154,406,336,240,431,49,144,95,242,126,91,48,490,34,20,16,147,58,21,92,9,90,202,89,161,39,91,94,325,65,5,504,41,61,247,222,223,101,66,52,69,85,36,47,607,141,161,131,207,69,275,43,310,37,91,192,41,71,7,307,257,580,128,91,157,520,56,168,104,127,258,72,101,179,197,90,2,174,8,47,126,60,20,24,139,158,115,103,215,22,298,6,279,113,120,183,161,382,44,193,22,405,2,12,128,199,253,12,51,16,157,188,59,320,310,128,101,644,179,2,27,78,88,182,230,80,251,150,321,96,18,228,185,283,429,61,177,366,161,212,403,281,34,113,136,16,123,20,156,35,159,141,49,10,42,93,194,51,322,321,51,59,22,130,105,26,470,50,30,21,326,51,366,198,65,269,39,211,137,76,81,172,57,91,216,137,400,158,115,247,83,84,171,134,284,29,7,41,346,46,261,87,76,473,228,385,94,28,148,275,154,200,314,77,541,17,227,247,101,48,122,132,22,54,44,396,39,242,109,50,104,51,36,29,74,62,87,40,207,27,11,450,123,131,24,140,28,426,207,320,381,101,159,137,401,4,89,111,14,797,89,135,99,659,175,90,41,136,383,53,124,222,37,274,252,290,16,101,266,81,313,221,261,173,489,10,315,70,108,116,197,151,84,37,11,150,66,71,36,270,25,195,37,338,347,494,171,96,49,225,153,360,496,108,196,161,247,194,12,70,157,133,232,141,180,7,470,164,2,141,295,9,473,92,127,235,4,548,592,75,329,55,103,81,281,62,57,148,206,116,390,74,167,189,131,43,38,85,82,46,25,241,224,55,259,15,246,294,230,278,22,28,3,187,23,146,106,57,160,477,201,94,318,64,63,34,352,238,528,220,27,880,107,17,98,24,148,159,37,66,442,41,37,17,156,56,135,129,846,335,83,136,110,15,348,292,138,313,15,16,461,11,82,26,310,87,111,6,39,201,18,59,271,235,2,137,539,24,100,124,257,314,314,28,665,74,69,149,219,29,270,163,61,35,75,26,171,44,339,14,58,36,80,272,67,103,19,124,107,162,22,250,191,161,460,321,94,254,7,270,29,314,3,149,66,72,24,135,298,8,30,47,13,31,538,443,188,58,472,246,249,190,524,354,25,444,91,10,250,96,435,558,64,77,48,167,182,218,182,211,163,87,114,218,5,142,150,6,12,92,23,143,34,307,256,170,257,40,76,21,196,234,441,174,196,52,71,83,90,52,13,72,24,533,106,39,283,317,194,88,275,189,263,135,61,37,106,114,36,53,521,7,260,127,69,239,49,101,249,26,56,13,11,41,66,180,384,191,81,560,211,647,463,142,233,55,11,64,23,436,281,96,53,26,49,126,227,54,79,94,661,322,77,621,12,80,135,337,196,67,36,64,14,184,204,24,17,79,165,179,36,107,53,305,96,14,6,141,74,79,138,47,78,408,215,114,160,232,47,70,77,154,271,93,148,107,131,36,94,40,188,15,222,252,21,88,376,187,78,187,165,24,102,541,95,185,204,11,36,283,117,38,263,171,119,197,295,53,75,114,47,191,9,227,22,28,79,251,745,127,52,154,215,24,43,473,14,115,395,364,61,364,396,491,115,33,97,116,28,102,14,156,43,23,16,174,425,111,89,126,23,179,201,561,12,159,54,260,2,220,68,84,35,253,78,227,256,102,353,91,30,422,128,140,70,11,120,137,158,394,336,72,17,125,32,424,339,40,303,482,29,72,261,563,54,84,283,129,71,243,71,388,173,63,136,35,68,565,273,116,17,54,322,19,404,44,3,41,151,99,93,107,136,9,28,43,210,135,24,10,25,150,214,80,134,176,779,137,18,270,644,323,85,216,30,285,134,179,64,82,5,75,251,87,24,38,27,391,224,428,377,882,563,18,230,75,130,251,133,71,145,105,20,993,49,354,130,219,2,116,136,54,50,94,168,70,180,3,139,167,179,384,27,95,48,189,314,80,131,154,2,137,194,532,47,7,42,31,116,114,843,257,211,14,173,84,260,7,42,42,238,302,28,346,337,6,66,297,69,125,27,310,32,16,475,173,33,149,42,162,251,179,223,27,246,320,157,174,129,147,93,27,20,343,14,4,129,155,10,67,158,175,27,32,236,615,52,80,97,23,197,70,45,19,86,60,175,357,215,147,207,4,31,484,76,214,97,113,103,126,167,319,96,8,438,135,173,36,494,203,46,28,175,59,207,220,131,139,71,221,20,3,419,89,198,251,299,287,340,68,29,126,78,536,18,162,55,51,29,8,26,154,80,486,143,174,261,542,224,240,72,51,141,8,213,331,363,38,57,60,200,202,107,271,598,401,80,18,39,275,134,3,595,170,265,70,364,82,187,73,99,61,41,112,170,157,5,322,21,305,255,16,195,17,258,342,302,173,120,8,47,123,13,339,53,3,103,116,59,546,59,37,82,16,101,287,23,361,290,153,44,21,12,146,431,52,234,57,211,103,316,132,5,18,57,157,315,72,68,95,240,186,20,71,53,494,162,473,102,131,117,30,8,167,182,90,142,17,136,102,16,6,40,148,14,82,319,110,63,149,57,143,174,123,367,5,47,40,155,60,281,157,116,68,122,364,51,6,3,60,20,47,83,129,89,165,111,24,361,205,167,107,33,76,103,51,109,321,184,502,22,85,364,129,57,310,90,19,12,177,284,55,228,105,16,278,100,71,24,166,22,195,564,94,249,27,403,106,68,28,94,9,559,50,206,37,215,270,110,81,97,227,86,222,26,200,11,521,155,19,311,37,3,31,91,330,165,360,3,119,139,76,683,84,153,4,600,178,80,192,43,278,203,320,11,369,267,148,129,290,144,9,10,25,179,22,22,127,27,270,176,264,82,2,101,393,104,204,154,285,205,200,211,693,257,287,26,44,23,136,347,83,91,29,121,3,122,19,459,10,96,517,526,82,312,65,188,43,521,51,192,102,163,27,19,477,263,31,14,67,66,25,109,195,212,64,318,50,376,49,231,141,480,8,167,334,122,168,67,68,35,130,108,146,378,73,187,42,57,49,290,64,45,94,8,68,119,225,110,352,664,85,36,347,41,112,213,47,181,9,35,716,228,228,122,184,82,117,143,46,223,9,82,26,103,836,90,298,175,28,2,342,67,426,76,54,269,410,22,151,851,155,331,191,72,110,28,111,89,628,4,17,52,126,214,37,30,70,137,528,24,94,52,164,71,599,125,76,333,319,155,8,210,214,18,126,145,37,246,262,339,92,180,65,74,188,178,63,103,7,9,36,171,559,281,42,260,6,109,132,35,275,229,127,90,97,280,195,173,11,105,122,70,12,158,57,460,244,122,263,56,60,2,15,68,170,399,31,369,256,92,45,131,390,5,377,26,30,244,90,411,57,690,72,57,43,67,100,198,91,171,252,52,209,87,95,207,20,15,270,22,182,56,22,101,140,124,123,247,297,16,160,519,47,22,296,69,250,55,100,34,45,169,42,301,157,88,50,91,423,92,163,29,84,112,88,49,243,21,159,163,67,113,90,492,438,349,69,44,102,270,392,11,15,202,156,462,206,172,32,337,734,235,37,143,357,369,788,336,218,330,24,8,54,71,226,448,306,141,136,3,318,138,25,4,174,231,148,207,70,105,28,79,666,50,40,245,164,93,31,153,205,8,227,111,10,67,27,56,104,110,749,165,65,125,235,36,49,259,71,270,213,99,51,19,21,280,219,386,39,19,227,185,229,65,22,46,614,272,88,90,456,272,227,627,101,59,115,394,32,170,341,260,394,240,111,353,93,18,356,107,9,69,113,197,4,48,428,10,338,468,340,334,128,392,71,28,27,348,69,64,283,63,40,372,122,142,563,260,45,197,2,46,232,255,6,194,232,139,70,150,117,150,19,95,49,318,151,18,98,28,262,223,117,52,95,20,77,4,264,54,141,116,337,334,52,74,609,136,394,322,3,816,299,131,185,15,68,4,156,50,123,4,97,99,434,430,217,21,79,164,364,205,33,38,428,252,48,3,42,9,51,91,417,288,25,210,88,2,230,16,95,195,263,54,292,50,187,76,299,387,102,128,342,62,21,25,262,327,42,65,8,28,39,31,118,761,89,55,53,52,297,125,58,15,87,89,73,178,172,230,247,33,138,381,272,181,231,54,159,43,138,61,124,68,52,407,126,44,7,251,39,80,30,175,318,5,59,3,429,167,159,13,129,22,462,113,60,33,31,60,182,95,78,55,71,329,21,172,77,15,178,91,68,88,74,143,323,65,353,104,371,308,148,121,7,138,36,57,121,74,95,36,470,10,245,28,30,32,39,97,64,361,8,320,40,276,96,81,151,22,143,78,2,110,393,105,541,67,187,253,45,367,158,46,521,116,56,29,116,422,108,45,47,22,263,162,290,173,31,84,44,78,145,123,41,47,36,480,321,113,167,528,69,191,51,48,12,66,356,204,350,64,227,190,171,144,151,187,118,16,611,71,163,68,114,24,286,45,146,57,261,187,205,274,89,81,4,64,366,40,208,245,13,154,261,82,107,142,131,302,272,250,4,72,32,19,6,94,66,8,179,216,169,2,117,32,65,79,5,136,220,201,717,335,215,35,77,119,379,226,123,170,241,120,105,43,128,307,390,21,61,124,254,20,164,132,248,90,160,119,27,13,39,12,113,199,84,67,40,103,59,195,57,42,3,86,2,2,26,7,30,362,11,83,32,256,50,86,5,3,236,81,13,113,4,33,126,28,21,372,490,122,94,105,40,195,3,80,204,38,656,136,193,52,246,54,184,195,503,27,139,53,470,140,75,134,102,484,115,171,538,197,109,17,33,56,40,22,560,470,123,101,37,9,154,83,403,23,110,152,168,2,165,448,174,246,33,315,134,334,3,42,98,62,20,8,289,31,610,6,77,10,53,241,235,47,82,196,121,38,47,161,39,234,371,95,153,14,76,76,225,70,288,105,179,61,164,38,81,307,28,230,83,98,481,622,532,238,12,316,205,318,46,4,85,4,464,81,224,18,37,346,148,464,176,113,23,157,139,301,87,645,13,54,16,151,96,368,20,191,275,634,74,74,111,575,5,121,485,175,27,7,8,206,277,83,192,342,26,98,30,332,171,252,167,23,179,32,7,43,483,342,216,205,78,31,109,152,57,26,66,56,214,468,201,12,462,157,72,24,125,43,93,73,42,34,218,97,136,152,341,8,118,454,54,77,372,95,65,19,40,85,540,353,406,361,96,18,269,233,182,60,135,158,346,37,51,243,32,61,47,20,205,4,167,143,254,256,113,16,12,221,71,8,365,46,47,355,3,79,151,727,396,363,118,320,669,34,182,806,9,92,52,32,56,10,68,18,422,125,95,65,74,235,54,176,175,74,300,578,25,88,120,11,252,31,385,87,11,19,57,27,824,174,20,57,115,119,171,141,39,70,372,56,189,9,235,144,48,842,188,111,278,381,166,141,96,178,50,11,6,440,103,500,76,243,269,204,64,343,73,164,34,33,72,226,463,54,47,13,62,270,20,92,282,2,55,641,29,4,574,88,244,159,9,40,63,231,125,4,56,367,13,551,57,56,72,530,252,39,24,14,212,216,383,38,150,363,33,203,15,197,270,261,28,14,244,6,18,223,78,52,2,555,47,312,9,453,283,461,49,180,18,102,50,346,443,88,405,147,63,130,72,112,176,124,74,166,130,394,226,145,398,51,238,59,15,63,41,98,9,80,141,414,96,101,197,62,331,9,372,39,24,31,25,70,48,458,5,73,260,54,290,206,119,389,22,37,5,373,419,238,123,158,203,60,769,449,193,67,250,141,84,8,116,215,162,8,38,20,34,432,57,6,20,102,150,149,120,53,190,184,215,41,25,93,250,119,46,6,224,325,177,170,188,35,94,37,112,256,384,16,315,66,134,149,237,370,145,92,123,448,7,79,342,39,137,545,97,141,248,677,120,88,92,66,409,66,93,117,34,324,67,19,3,190,50,99,200,117,54,162,3,73,43,95,213,291,191,164,61,190,134,62,270,389,41,259,11,7,394,682,161,67,218,686,18,125,55,178,447,215,25,292,139,278,277,173,51,44,39,155,102,95,172,231,9,102,147,198,237,25,350,135,376,33,98,75,631,102,68,134,42,328,38,87,90,84,34,177,96,301,219,253,51,64,6,35,410,463,74,2,87,155,142,108,34,41,104,173,355,59,34,114,277,137,229,16,46,394,176,29,85,69,263,36,205,312,370,26,561,69,364,72,34,44,38,176,213,8,213,96,25,275,291,257,70,207,110,128,83,470,252,5,425,203,296,111,143,52,509,49,169,150,157,410,33,70,679,189,16,158,194,24,176,30,263,102,10,95,503,114,295,208,453,254,44,562,142,50,113,372,112,53,480,143,129,25,2,29,8,76,5,319,373,140,361,63,91,364,79,185,94,8,5,221,5,98,28,172,100,55,115,40,32,136,236,135,221,64,102,9,181,64,84,356,185,178,154,176,190,320,230,213,139,29,171,65,190,24,281,167,295,24,215,33,150,275,383,85,335,387,28,79,142,463,344,286,61,140,194,100,153,30,58,335,229,629,363,63,79,249,153,413,6,186,387,476,166,203,64,109,196,115,289,120,130,29,187,530,235,72,34,304,112,114,49,72,33,83,203,568,213,97,58,32,294,97,251,220,84,19,261,94,97,429,124,256,156,80,155,72,190,212,29,81,60,146,6,40,231,52,107,118,11,283,481,101,200,25,145,2,302,73,85,3,351,35,10,203,8,170,174,135,135,331,150,130,43,335,70,104,378,20,223,70,15,109,41,397,283,148,171,63,13,275,171,397,39,216,44,20,131,75,78,24,107,210,172,31,6,308,121,224,88,15,170,36,46,37,130,6,233,49,53,253,51,171,527,490,150,167,139,385,76,273,314,220,44,209,185,263,46,181,197,85,64,238,11,39,175,161,64,72,58,336,11,7,46,640,361,508,209,34,520,72,21,39,64,85,70,17,7,327,84,34,36,82,187,57,56,396,499,278,68,51,569,226,53,402,15,331,125,115,376,316,156,70,106,169,118,280,286,114,99,155,41,324,107,143,203,18,167,96,157,88,29,9,678,50,189,21,222,107,58,49,273,3,121,104,66,20,95,58,453,116,27,535,173,210,164,95,201,38,127,58,31,11,199,139,518,101,49,49,61,402,41,30,52,293,225,85,112,63,158,136,162,15,213,131,49,62,306,400,29,66,161,326,62,139,21,101,343,86,447,28,42,281,157,65,277,77,119,230,78,29,39,30,462,254,80,346,37,129,417,206,163,159,54,228,73,21,316,63,12,72,183,15,99,176,18,73,178,49,77,124,173,17,57,133,246,543,486,600,33,232,240,72,111,317,59,55,432,104,157,530,335,353,39,49,67,117,48,175,222,193,125,67,75,347,284,47,561,228,76,150,6,186,171,60,73,198,56,30,218,107,5,57,398,10,459,490,474,414,118,86,262,431,11,538,448,188,141,168,76,60,146,223,20,464,120,80,30,18,212,5,229,29,142,156,466,192,64,18,358,79,82,96,109,70,21,702,412,56,63,13,223,150,110,250,80,156,172,391,364,578,91,66,159,95,284,403,120,148,362,81,39,43,120,535,472,32,203,47,48,158,781,86,201,25,128,90,102,14,363,306,278,11,270,125,55,25,212,73,50,155,67,37,84,427,116,83,11,220,10,80,227,229,37,90,405,74,56,276,159,316,73,28,23,118,230,139,67,5,37,3,53,564,127,275,30,190,58,304,21,247,54,328,369,15,43,150,88,19,133,481,312,238,5,65,106,405,5,228,134,59,31,53,213,19,4,71,153,68,82,42,21,150,175,95,198,112,192,125,156,49,33,25,256,34,197,411,50,59,44,397,187,76,64,286,171,78,44,55,429,8,32,116,109,206,502,356,49,39,124,166,238,389,253,13,20,54,11,115,49,260,2,253,33,69,7,39,148,36,60,211,166,52,676,409,13,117,277,187,81,271,41,59,285,6,271,742,19,271,116,93,31,19,174,280,340,52,92,170,29,253,128,277,362,285,101,66,34,22,305,95,168,107,32,80,23,179,361,193,487,3,39,226,68,86,213,148,505,224,23,264,231,832,162,53,470,66,151,39,177,424,248,375,106,81,444,313,106,85,62,21,183,13,225,308,87,359,621,81,101,231,157,87,151,223,173,117,51,70,372,194,22,54,86,312,443,26,659,141,349,12,72,29,205,106,515,266,43,246,248,106,33,150,327,43,133,302,15,267,197,109,229,9,527,101,60,117,87,59,43,6,27,165,346,177,23,46,73,71,98,50,14,57,14,41,58,44,542,540,100,33,383,93,51,224,274,390,93,126,7,116,20,16,154,66,85,95,38,71,48,395,19,86,40,281,103,6,276,226,169,378,96,842,40,7,63,400,9,262,65,144,111,67,127,393,37,62,54,29,98,121,109,11,76,171,23,383,11,253,131,87,244,395,66,426,257,79,399,17,77,53,576,77,157,352,158,79,165,166,105,2,209,409,64,502,3,295,89,245,38,3,83,156,163,47,87,164,99,29,52,70,112,72,509,294,170,158,112,34,17,28,42,216,150,24,180,209,104,248,31,291,42,112,192,61,47,572,114,291,150,138,38,89,305,14,18,37,15,104,43,151,301,170,253,11,241,48,126,159,442,127,51,233,403,75,270,103,271,82,57,149,6,91,38,49,409,282,7,96,607,196,7,926,224,2,2,144,194,175,387,39,81,655,63,87,114,605,111,26,364,463,236,199,94,9,364,35,209,18,178,23,23,8,257,168,125,153,353,149,233,80,80,51,109,69,17,59,194,42,956,74,5,390,97,365,92,139,194,228,26,175,32,62,415,22,246,30,106,76,253,91,45,51,92,82,166,22,216,4,125,27,54,514,16,37,197,82,28,99,70,5,22,109,190,211,475,264,76,305,51,52,144,465,281,323,126,522,608,456,43,134,25,72,96,92,664,46,65,16,275,339,41,104,35,74,149,308,206,507,135,330,510,352,268,470,413,187,118,240,420,69,6,225,250,14,128,36,6,275,220,322,175,96,322,91,139,208,340,129,11,6,358,644,18,41,55,82,277,202,65,57,31,369,306,30,269,154,44,568,364,78,97,3,48,419,159,104,252,66,86,235,75,106,83,369,130,209,285,59,62,37,289,113,125,183,105,38,412,82,132,242,88,119,174,59,405,106,386,303,20,63,126,6,181,476,42,178,244,63,30,108,13,282,44,71,559,122,777,77,103,86,167,213,391,12,230,53,77,135,208,93,200,19,102,137,186,2,18,332,30,641,159,526,400,363,165,84,186,33,126,68,182,151,210,443,126,73,52,64,121,284,75,377,85,339,452,6,280,45,162,120,152,36,262,170,53,4,4,28,49,318,63,93,291,100,125,49,14,6,114,386,125,246,70,130,21,135,20,394,66,19,8,188,627,426,337,14,25,56,215,82,45,181,147,89,33,33,210,106,536,22,722,298,92,20,58,166,76,171,183,7,228,48,231,71,266,87,49,29,333,6,163,200,14,18,44,400,248,26,12,34,323,68,78,160,5,100,104,31,37,89,92,120,110,349,51,106,34,264,24,88,30,59,53,24,132,160,117,72,116,178,5,506,26,394,128,182,333,29,138,19,18,17,92,21,8,249,28,106,7,29,342,49,611,51,6,117,18,8,62,271,4,27,49,34,83,242,106,128,281,65,208,7,80,95,406,174,55,37,161,237,57,615,89,99,4,108,33,560,125,87,129,98,80,101,417,215,181,33,79,63,203,222,102,84,79,593,114,176,222,123,264,147,94,423,126,264,479,164,224,206,252,157,278,115,132,14,212,497,299,92,23,133,22,346,17,206,110,268,38,145,76,273,37,89,59,76,645,509,230,421,118,57,532,156,174,43,365,56,87,146,68,8,151,41,350,140,112,663,84,35,211,27,270,62,286,44,2,96,236,93,30,340,143,181,12,114,312,378,146,256,58,265,199,322,52,31,207,257,107,282,11,22,172,229,18,7,456,129,131,114,321,44,204,26,207,77,247,52,496,319,140,119,64,474,131,119,198,670,30,61,193,255,35,42,154,86,40,474,4,312,49,140,105,208,749,7,5,134,77,181,110,8,42,32,76,4,111,115,136,53,104,130,44,22,149,80,269,126,118,509,21,162,35,36,384,38,125,92,131,134,120,215,595,410,239,153,282,138,57,154,462,435,126,215,399,154,77,44,86,190,130,36,266,78,55,82,144,66,6,139,54,95,53,206,279,69,626,107,60,70,18,17,130,70,7,74,205,20,45,57,42,422,255,36,219,82,236,66,12,197,187,197,138,83,288,218,4,199,400,75,187,646,225,89,88,101,100,141,105,202,373,240,220,897,20,134,276,135,16,37,166,127,277,608,133,36,184,77,57,133,343,380,65,351,112,289,281,396,257,73,75,100,94,74,57,106,295,19,120,141,487,150,404,21,102,387,301,324,45,56,363,213,36,315,31,36,39,8,29,262,14,170,330,158,153,10,258,84,8,444,371,19,560,25,149,498,198,273,299,84,251,119,107,221,357,160,10,152,4,29,20,23,52,6,10,314,138,86,42,220,89,391,128,72,38,49,199,18,59,32,170,110,47,208,24,155,87,25,56,225,405,18,147,37,181,641,10,34,43,160,158,347,53,590,93,130,4,60,441,7,78,150,371,168,23,387,407,51,119,194,329,87,108,207,56,45,310,64,418,450,304,407,186,266,93,67,216,22,81,40,22,137,145,250,80,30,137,14,627,21,51,30,760,53,130,53,129,261,34,48,116,143,78,161,536,116,117,21,191,234,74,35,331,48,66,11,452,192,105,34,252,198,16,82,124,99,397,103,14,263,39,46,149,153,95,233,2,98,142,444,127,77,120,50,34,96,318,435,18,632,106,121,145,485,22,25,823,252,271,74,69,115,54,293,162,61,429,23,77,72,53,61,39,13,84,218,19,112,36,25,253,150,8,40,833,99,14,364,225,608,214,625,240,70,156,10,33,220,390,49,203,234,363,142,26,48,80,20,26,29,67,153,168,400,221,304,87,8,207,64,476,133,57,194,832,33,109,42,20,233,103,1016,70,114,290,435,546,22,126,251,125,36,31,228,529,160,44,199,53,2,88,82,8,38,100,124,40,165,311,315,442,105,323,387,19,7,212,47,53,326,72,124,417,206,859,123,51,321,345,59,75,106,233,128,6,314,156,382,203,47,398,86,55,528,382,20,26,486,125,160,90,165,87,91,49,150,37,540,81,362,55,292,205,68,17,52,40,200,20,168,61,75,43,44,42,15,172,461,160,603,238,399,108,18,347,495,125,242,336,348,129,151,203,694,587,247,294,88,125,115,48,137,23,111,34,199,266,426,268,95,3,91,261,98,412,123,24,90,14,5,207,12,209,66,458,151,121,78,67,116,199,10,58,88,49,5,145,314,117,296,6,55,226,47,62,376,33,21,209,549,443,18,471,72,13,57,438,65,80,175,111,331,143,426,12,88,139,15,250,230,40,22,87,234,120,2,520,108,181,222,438,232,29,5,141,5,164,542,177,33,120,15,73,454,56,29,160,4,14,53,154,132,137,435,151,174,69,127,105,172,332,20,427,340,20,17,79,130,111,7,13,129,715,223,157,94,176,51,71,129,52,22,153,117,495,630,41,210,45,174,61,13,18,35,40,440,189,169,279,137,65,154,10,619,100,111,416,10,72,8,82,75,93,296,548,45,416,28,262,177,230,96,683,98,283,343,15,210,255,7,215,306,418,37,99,193,136,239,201,211,204,207,80,97,22,201,99,242,399,540,89,33,379,47,268,62,55,48,159,208,76,30,352,463,42,274,111,168,518,65,21,90,61,364,30,53,50,286,304,134,72,27,83,214,242,34,67,118,269,306,6,17,144,624,80,64,24,85,87,339,6,197,166,62,259,73,226,504,285,33,112,408,378,188,178,16,270,328,219,59,115,76,10,76,104,433,70,79,529,189,201,154,207,395,635,175,227,370,217,184,3,80,84,168,329,94,110,363,58,77,473,86,86,451,34,37,5,138,89,275,342,296,18,204,195,76,123,237,263,393,97,60,62,35,72,103,95,140,166,88,566,169,459,115,102,204,90,405,303,215,82,101,36,202,107,293,27,54,55,32,195,184,11,529,160,111,199,111,76,75,21,34,251,104,46,207,121,280,83,183,559,28,21,452,349,77,34,52,121,34,13,316,205,119,274,329,33,181,575,153,117,206,133,55,141,76,75,26,205,198,458,23,537,122,57,114,33,178,103,244,35,42,244,4,43,60,47,145,445,120,297,102,108,226,213,189,87,93,5,15,56,192,876,126,59,668,41,100,452,76,597,311,30,78,30,40,115,283,251,231,29,147,186,11,135,302,923,34,88,221,31,107,253,19,100,84,444,206,230,306,73,101,132,194,14,425,58,193,5,182,61,23,143,65,152,180,71,476,115,221,86,29,24,77,100,411,86,520,383,32,128,70,191,111,1021,317,33,170,272,48,288,430,77,153,325,291,143,123,169,33,184,288,47,252,46,100,187,136,100,161,70,77,119,60,84,730,557,200,71,210,356,254,239,143,28,240,97,107,171,199,440,239,21,8,590,95,103,169,82,57,158,8,493,50,298,639,130,204,15,387,263,55,143,520,229,204,13,156,29,263,265,46,28,371,106,159,270,78,299,80,636,353,112,35,208,448,14,7,102,55,89,5,142,115,7,30,538,117,180,167,203,263,158,728,80,321,220,116,35,209,198,181,11,12,15,26,478,74,274,241,180,81,31,693,24,40,12,102,84,225,170,121,40,4,299,28,60,208,74,107,374,244,150,8,172,66,126,177,18,63,13,108,65,103,391,89,191,180,217,54,37,155,253,19,246,345,288,391,183,507,26,37,86,531,15,162,103,251,260,226,253,193,70,60,319,38,7,28,210,190,120,81,103,114,574,15,245,361,15,111,2,34,102,606,82,58,415,93,102,498,84,16,267,2,445,74,65,80,183,67,137,6,117,113,290,45,31,155,425,373,6,5,219,89,292,9,61,198,83,98,107,444,27,158,249,66,295,275,349,130,154,655,173,105,243,47,137,101,616,116,158,30,266,636,273,71,33,41,63,10,227,201,130,85,121,61,205,223,486,60,328,95,84,220,97,75,209,90,157,31,168,12,201,347,33,7,56,145,313,30,481,229,85,937,172,508,274,265,107,74,96,47,59,7,74,9,44,221,149,390,170,31,94,47,94,155,829,202,109,33,209,76,547,132,60,202,116,259,89,119,221,186,433,311,130,143,182,212,141,112,314,536,125,43,91,11,46,29,38,132,281,373,150,298,155,82,27,140,666,43,91,125,371,267,4,33,37,73,50,67,74,557,34,43,95,116,10,372,28,90,24,249,37,150,118,162,308,164,76,3,283,128,283,326,138,346,46,20,113,281,96,69,126,481,169,18,164,603,508,109,72,274,384,366,133,158,49,246,532,13,84,146,289,148,112,138,210,396,341,21,132,310,710,100,539,76,13,350,123,348,132,183,465,287,23,110,438,553,100,181,132,337,423,277,74,63,9,120,92,44,10,92,75,164,343,490,404,544,476,300,187,148,164,54,4,132,163,290,39,65,204,139,39,49,112,89,184,111,357,43,305,13,147,681,76,183,302,75,31,363,30,26,167,291,218,56,74,176,39,258,11,29,110,59,131,332,69,96,234,635,705,76,30,45,566,487,52,427,435,226,69,82,218,341,92,60,899,273,21,172,13,73,36,31,35,243,139,77,147,410,87,379,367,74,31,34,173,330,87,47,183,185,243,115,18,266,192,34,4,437,152,303,75,79,65,221,98,297,64,159,30,78,48,453,40,431,241,61,30,55,19,102,219,155,392,74,40,49,77,32,95,183,90,209,51,130,116,29,289,181,205,121,118,24,23,233,330,256,162,249,59,129,210,112,165,439,30,154,12,16,103,72,571,12,38,28,59,13,488,397,335,400,36}; +__attribute__((section(".data"))) sh_uint32 test_malloc_big_size[1000]={13,15,3,5,19,8,9,10,11,7,23,7,9,23,12,7,9,5,11,16,3,3,10,9,22,2,5,25,21,21,6,2,20,6,5,25,6,22,18,11,19,7,21,11,7,20,7,12,10,4,17,16,10,12,22,11,9,7,21,7,9,15,25,2,15,14,2,4,13,7,10,25,8,25,5,22,17,6,19,18,4,24,2,13,3,22,12,2,2,14,3,13,5,21,24,13,20,10,22,10,2,18,2,7,2,5,20,4,22,11,25,19,13,25,10,4,21,16,14,12,11,10,7,20,4,20,18,25,24,5,18,22,17,11,19,6,16,2,7,25,5,5,5,11,21,10,25,17,20,12,12,14,11,17,10,19,18,6,5,17,17,21,14,5,13,6,4,9,2,5,14,15,13,9,19,16,10,25,15,17,7,24,14,8,4,19,16,2,3,24,5,21,18,9,2,18,22,21,3,3,25,24,10,5,14,9,17,4,3,21,14,10,19,4,13,24,19,6,17,10,14,17,13,14,14,5,10,23,9,5,13,8,11,4,23,24,7,14,14,12,15,3,19,5,13,13,13,16,19,22,21,7,19,22,16,16,14,15,13,13,3,17,18,17,23,10,19,11,21,3,17,21,10,19,4,14,4,20,19,5,2,25,2,24,20,8,7,12,8,14,15,22,5,7,10,8,24,6,25,12,9,5,16,24,25,16,3,20,16,18,10,8,15,7,21,10,13,17,22,23,11,15,23,24,4,10,9,14,3,21,3,17,3,12,6,22,8,17,23,21,6,2,5,16,6,8,22,19,20,19,16,12,5,13,6,24,17,2,15,8,8,11,5,2,11,25,14,13,11,13,15,18,14,8,24,13,24,3,15,22,14,5,24,23,3,7,8,9,4,24,8,24,13,18,2,20,12,10,25,7,15,3,24,7,25,6,7,18,3,11,20,12,3,6,4,7,7,18,24,5,17,12,10,6,5,12,18,14,8,22,2,9,24,3,7,18,24,24,17,16,14,19,25,4,6,23,16,14,7,2,13,8,20,18,12,19,5,13,14,6,14,6,17,18,14,16,19,9,4,3,14,23,10,17,22,24,3,25,11,5,11,7,7,6,7,19,23,20,8,22,17,9,7,5,10,21,22,20,22,24,21,5,10,8,13,8,22,7,3,9,9,7,11,25,9,4,19,19,2,25,22,5,6,16,4,5,10,6,25,19,18,8,3,10,5,18,20,15,4,3,25,9,12,6,11,18,3,10,2,20,13,3,6,22,18,4,6,25,8,10,19,20,4,6,15,25,14,10,9,2,7,9,2,24,9,14,8,21,7,18,17,24,6,25,4,12,13,21,4,14,17,5,9,6,3,6,10,2,16,12,9,17,6,23,6,3,9,8,9,8,4,19,18,16,12,13,25,23,6,12,14,22,18,10,8,4,18,20,19,4,13,9,22,2,21,12,19,21,15,21,16,10,4,7,24,6,12,16,5,22,4,17,8,12,24,18,2,19,14,15,25,24,11,3,5,15,21,8,18,3,17,23,6,8,5,13,21,23,11,23,6,4,15,8,7,21,13,5,24,17,10,11,10,4,20,23,3,3,8,22,10,17,20,25,12,17,5,13,6,7,5,12,10,2,23,11,14,12,6,2,14,7,21,13,7,21,3,14,18,11,22,18,7,11,20,10,8,10,14,10,24,18,20,11,3,22,21,12,16,7,19,25,21,18,14,15,23,11,2,14,4,13,21,7,25,2,8,11,9,24,18,19,4,14,3,2,21,18,13,18,9,15,18,19,7,12,14,4,21,4,16,6,9,17,25,23,18,4,18,17,4,12,7,20,8,23,4,10,11,16,16,5,23,22,22,12,9,22,20,25,25,8,24,19,25,20,4,14,24,8,5,13,10,14,22,7,7,8,10,15,23,10,2,25,4,17,3,8,15,16,8,17,14,18,25,17,10,6,23,14,24,20,3,15,8,7,10,10,23,3,22,18,16,15,3,20,11,15,11,16,10,15,24,23,14,19,25,8,9,21,18,15,13,10,9,24,19,11,17,6,3,6,7,20,3,5,11,20,4,19,13,25,13,24,10,19,5,21,14,11,11,11,2,7,25,13,25,17,19,20,8,9,8,3,19,19,11,22,3,15,24,17,17,8,7,25,7,9,16,2,20,14,6,22,20,7,12,11,11,4,5,16,25,8,10,21,5,2,14,3,14,2,17,13,11,21,17,17,25,11,19,18,3,25,15,5,5,17,12,9,20,20,19,19,19,14,23,11,21,9}; +__attribute__((section(".data"))) sh_uint16 test_malloc_big_alloc[2000]={205,825,991,478,947,552,976,42,988,441,354,888,628,164,48,148,154,293,26,719,31,896,412,803,407,635,764,820,556,105,608,156,948,4,243,670,473,454,58,2,374,920,361,461,880,329,849,880,380,715,71,906,869,420,778,790,202,470,280,985,278,537,560,739,256,809,902,419,936,325,329,192,263,5,86,830,251,458,721,406,106,702,321,981,574,371,853,698,427,851,64,126,190,27,476,914,143,276,605,124,619,290,904,590,892,988,338,548,9,753,530,615,750,613,387,39,822,235,845,598,605,697,388,889,633,576,224,703,614,253,65,831,3,204,628,705,930,905,853,446,871,745,774,748,592,611,232,886,665,180,326,483,267,872,278,608,131,368,245,437,287,977,313,379,552,970,615,519,883,148,339,529,801,651,286,285,687,624,324,417,419,910,271,624,25,800,664,178,739,513,769,241,678,59,342,414,872,876,123,620,483,909,77,896,694,962,514,890,612,926,527,328,637,832,56,367,998,190,232,349,201,317,266,656,713,294,810,153,464,791,6,299,999,130,374,881,556,790,689,868,254,948,191,903,54,299,554,841,240,383,723,381,434,62,499,438,216,37,187,701,328,971,601,859,816,402,13,72,622,227,875,310,949,634,963,549,784,870,13,763,995,19,99,718,585,509,34,261,751,142,614,207,870,562,949,982,736,112,112,913,16,447,19,797,879,390,304,305,730,694,169,117,589,792,992,558,1,503,444,532,21,163,537,724,856,159,118,345,80,592,607,968,742,379,137,969,450,894,876,756,926,203,293,397,207,975,761,986,645,846,88,403,504,485,847,385,477,215,799,316,635,404,775,955,956,730,294,627,432,76,762,648,499,773,345,195,850,563,392,334,743,957,173,744,934,642,752,665,839,923,271,612,604,901,20,246,97,660,146,289,52,567,518,935,214,385,85,676,411,284,829,357,372,391,747,713,122,688,364,928,846,864,606,93,780,119,167,413,524,256,746,108,582,922,441,854,24,183,501,87,805,428,573,314,798,15,113,82,6,866,813,125,942,387,229,279,179,355,226,56,725,143,715,741,943,63,646,581,946,568,623,362,583,394,866,962,371,908,67,867,35,945,606,735,623,304,892,86,11,954,8,860,37,199,165,496,533,400,337,593,436,603,873,582,776,36,934,595,938,722,707,640,987,675,456,770,754,941,193,641,149,767,717,200,181,848,674,587,573,475,49,377,296,770,597,650,67,731,490,732,520,101,496,437,815,734,482,464,903,28,40,17,457,418,577,503,620,823,714,420,666,514,312,570,370,780,609,723,671,717,547,844,822,603,20,489,826,366,704,424,250,897,365,78,178,18,731,954,238,817,755,445,486,129,438,213,110,41,197,196,497,25,242,337,937,333,123,710,904,538,258,507,861,297,118,838,900,366,785,189,435,280,408,363,858,728,308,283,814,590,994,915,15,358,998,457,433,260,354,661,237,217,306,796,692,593,563,423,233,275,453,386,479,667,914,315,117,812,657,462,134,92,541,467,861,389,90,848,335,849,587,632,799,157,666,711,84,474,303,671,973,656,49,208,540,855,431,985,867,18,857,359,783,135,265,364,226,820,639,757,952,96,312,921,452,938,727,929,997,637,170,202,651,840,146,959,618,171,174,0,523,85,885,749,494,282,869,852,91,429,915,726,939,418,659,572,219,721,502,157,738,993,172,698,225,958,110,166,186,960,144,435,737,282,66,288,274,672,834,617,931,215,803,10,102,43,133,811,218,150,195,845,850,353,4,578,102,327,171,524,70,24,567,277,69,974,26,292,425,523,125,840,485,269,369,311,955,257,285,397,290,221,577,127,106,901,302,225,310,340,194,902,798,138,495,300,737,114,584,511,636,835,550,762,406,786,928,683,155,837,484,396,408,838,691,638,660,959,546,281,349,821,733,343,823,795,60,481,706,247,480,712,924,812,580,460,865,55,958,307,217,115,339,548,862,542,421,989,415,495,136,559,893,65,806,471,60,52,695,251,644,401,667,414,632,497,746,413,176,885,399,647,991,811,255,23,442,121,663,347,600,254,193,84,686,826,177,553,477,569,891,805,993,412,91,473,214,73,684,395,512,724,631,791,223,824,272,147,740,641,859,738,451,508,972,316,964,810,51,911,417,766,931,210,559,218,373,886,700,827,533,474,828,529,355,331,538,184,681,10,541,16,11,405,129,58,974,966,351,42,990,470,963,652,351,136,233,115,965,97,331,204,626,380,986,63,890,927,953,500,779,439,807,911,650,565,594,819,662,5,697,124,309,443,498,907,804,683,378,662,939,131,693,674,247,172,877,705,137,342,259,942,352,68,325,691,343,341,39,750,981,309,185,22,842,703,919,884,835,575,173,771,242,292,581,595,61,525,777,899,298,520,647,99,699,761,153,884,423,0,727,937,645,836,471,630,475,151,283,482,668,912,98,532,439,245,570,300,77,558,209,139,467,874,540,542,69,450,451,630,607,198,440,165,184,322,763,368,492,748,528,231,783,468,426,773,103,794,45,494,436,308,679,670,572,191,536,22,32,994,543,228,756,646,456,677,465,708,621,601,796,237,511,265,338,672,978,673,14,244,382,169,678,922,679,402,21,234,596,465,951,259,132,921,760,755,636,75,718,847,787,239,507,843,526,644,200,382,917,638,72,50,27,557,564,580,491,427,369,141,472,997,505,241,515,625,517,933,384,689,80,519,262,508,120,383,159,501,898,472,264,829,93,463,824,253,270,12,240,502,398,400,185,837,774,534,975,789,306,765,332,709,766,918,505,599,54,289,808,895,754,162,814,907,176,759,932,317,333,919,263,319,863,9,488,350,816,899,340,175,653,295,360,860,875,599,373,314,653,709,516,699,109,53,62,913,891,642,753,393,968,468,690,950,375,530,348,258,356,128,909,452,531,269,935,655,878,584,627,447,789,940,513,275,403,893,83,421,794,330,521,702,458,14,602,945,648,182,626,455,621,865,591,141,198,229,979,729,405,220,539,711,410,597,1,536,521,361,758,930,654,266,687,802,516,712,336,28,996,839,459,370,554,489,378,952,234,528,356,236,313,693,320,255,448,111,409,442,980,76,341,7,140,267,212,295,272,649,211,982,145,57,735,515,905,957,170,819,857,669,972,459,476,879,685,243,216,95,78,158,775,36,83,208,613,162,696,248,116,121,132,188,862,700,261,43,682,933,94,460,831,500,701,180,990,246,297,163,362,768,323,749,895,851,111,629,782,956,961,878,189,758,108,201,38,745,634,384,681,424,925,188,940,252,478,224,344,531,733,550,107,48,984,776,7,578,307,586,376,23,704,682,90,175,183,960,488,46,35,506,344,809,560,335,690,522,44,571,230,779,818,786,38,744,288,440,906,583,187,492,551,873,736,827,864,833,858,631,372,544,649,658,462,274,422,149,160,843,696,842,166,197,347,199,498,720,917,728,800,411,551,120,301,270,164,268,239,161,416,574,992,825,154,161,486,206,565,302,445,479,430,244,70,742,262,752,874,792,961,79,466,547,898,220,481,708,415,203,585,209,359,101,305,883,616,212,264,94,568,320,151,882,616,260,257,75,353,535,669,401,710,688,569,303,284,29,51,989,398,422,381,454,610,429,45,611,543,571,797,463,321,455,444,655,504,617,588,177,346,639,113,252,273,747,389,983,676,326,222,788,363,751,228,555,654,976,664,643,134,236,944,98,953,996,882,211,887,759,279,856,377,205,966,31,416,555,318,943,334,527,230,618,466,50,510,598,602,658,174,410,249,399,594,100,978,249,782,55,358,673,298,133,158,273,30,760,844,449,268,852,801,95,96,210,92,720,480,722,53,965,390,145,490,633,686,685,575,182,323,357,484,510,126,88,900,802,629,854,116,804,3,64,138,147,912,47,448,196,772,684,661,155,967,707,734,764,332,692,74,449,719,863,714,73,227,995,105,286,404,336,2,44,32,17,830,579,910,781,231,33,522,619,526,828,808,12,57,386,652,238,391,301,179,453,29,947,181,936,428,512,566,487,768,41,887,119,142,740,539,561,446,941,586,318,319,346,311,71,741,793,128,716,545,426,622,970,79,778,493,625,889,213,925,114,564,167,855,767,984,604,788,927,591,793,973,152,562,706,431,109,923,127,219,434,659,916,908,281,82,296,579,409,967,600,871,946,34,817,8,250,566,932,68,609,732,680,832,836,807,950,150,139,944,407,640,160,430,103,725,534,680,168,74,821,324,367,276,806,222,771,140,544,432,396,291,350,352,87,248,561,186,46,897,772,535,221,509,348,525,365,668,291,81,964,223,168,47,729,194,888,517,785,781,66,675,461,330,983,549,833,588,971,487,130,677,818,663,757,610,81,104,918,443,469,726,322,433,107,206,61,40,192,135,834,493,156,813,868,769,122,394,491,546,596,553,787,100,518,393,924,315,881,30,235,765,376,777,469,327,152,506,557,795,657,951,916,815,999,89,144,784,277,894,980,388,375,589,89,104,392,877,395,841,716,545,695,920,59,576,979,33,969,360,643,929,987,977,425,287,743}; +#endif diff --git a/shelter/lib/include/kernel/tests/payloads/test_pez_payload.h b/shelter/lib/include/kernel/tests/payloads/test_pez_payload.h new file mode 100644 index 0000000..7a0ef8f --- /dev/null +++ b/shelter/lib/include/kernel/tests/payloads/test_pez_payload.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MPL-2.0 +// This file contain the values to use as pages count for the benchmark of allocs and free with Pez +// It's autogenerated by tools/generator/pez_alloc_free_payload_gen.py +// Copy the output of this script in this file to regenerate it. +#ifndef SH_LIB_PAYLOADS_TEST_PEZ +#define SH_LIB_PAYLOADS_TEST_PEZ +#include "std/type.h" +__attribute__((section(".data"))) sh_uint64 test_pez_physical_size[2000]={1,591,1,132,1,1,1,193,79,1,348,1,1,228,8,1,101,1,1,157,69,1,39,1,749,186,7,1,1,1,83,1,61,195,193,273,56,17,30,1,1,93,1,1,1,148,49,1,1,1,47,47,1,1,13,65,30,1,1,55,1,1,23,202,270,89,660,1,41,137,1,1,1,1,1,163,1,1,30,1,194,1,1,266,194,1,410,199,1,1,211,38,455,1,49,435,1,98,1,106,351,149,23,114,1,1,119,100,258,230,1,284,24,1,1,1,1,1,284,1,291,1,400,1,1,1,1,2,168,1,1,1,317,180,1,330,1,1,730,1,42,80,1,1,126,236,1,311,1,273,1,1,1,1,1,57,1,198,1,110,1,1,475,151,1,1,1,13,1,1,136,1,1,35,1,340,5,218,13,313,68,1,1,1,231,1,82,428,97,1,218,1,1,45,1,1,119,1,112,107,159,1,1,1,118,1,1,46,1,129,3,1,1,66,1,87,490,115,1,1,218,1,1,17,480,1,1,455,316,3,32,754,35,1,1,1,1,110,1,6,1,138,1,165,99,331,166,1,347,88,46,192,1,46,1,1,274,1,99,1,1,1,1,23,221,271,334,1,1,1,1,1,1,1,457,1,171,1,63,405,1,3,1,8,1,1,13,1,204,277,1,227,1,1,1,359,1,346,126,1,1,1,382,181,187,1,201,1,1,289,1,1,1,18,40,1,1,129,64,65,1,1,1,1,39,48,1,22,166,10,57,168,599,1,1,1,202,1,1,1,40,10,1,20,380,1,37,212,132,1,177,1,1,45,112,9,126,27,1,1,100,111,1,1,104,22,1,250,1,1,23,147,1,81,1,1,110,1,669,1,184,156,100,161,1,43,1,255,1,1,1,1,39,1,1,1,1,1,46,1,1,119,1,1,39,57,1,199,151,1,277,408,71,475,1,198,24,624,27,1,1,1,63,222,18,15,1,1,6,18,1,1,1,318,1,1,192,195,1,1,127,1,1,1,7,1,1,1,221,60,1,176,1,1,1,1,1,1,92,48,1,1,227,290,126,64,93,1,8,1,1,1,72,138,1,95,84,1,118,1,1,89,1,342,79,1,1,173,1,190,110,1,1,37,461,180,197,1,1,1,85,60,347,23,27,1,1,1,1,79,1,1,1,1,1,80,166,1,103,145,1,1,1,29,30,1,1,181,1,1,41,111,149,1,1,1,1,1,68,1,1,433,60,1,1,137,1,1,16,6,239,1,115,6,218,108,1,49,1,42,279,27,35,185,1,1,1,112,1,1,1,1,1,1,1,167,1,1,263,1,1,351,1,386,1,1,1,252,1,82,1,102,1,38,20,1,1,45,1,1,1,173,1,445,1,312,1,296,81,10,51,1,1,67,1,136,211,1,201,20,1,1,1,109,1,22,1,1,120,137,62,44,1,1,1,1,27,1,1,19,40,1,1,1,213,1,1,1,1,1,137,1,102,96,190,1,15,132,7,266,1,459,21,1,1,1,1,214,1,33,1,7,1,1,47,92,1,1,14,247,38,1,335,98,1,1,419,605,1,27,63,115,45,1,1,1,1,1,212,1,1,385,251,1,69,26,33,1,1,27,1,1,1,1,58,163,1,1,1,1,1,34,77,1,1,1,1,1,1,1,1,210,97,13,1,1,120,28,1,100,1,1,30,1,171,122,288,1,27,1,1,64,58,195,67,354,72,1,1,1,1,1,1,88,654,11,1,52,1,1,45,1,194,85,187,1,28,1,1,1,82,1,1,197,88,1,28,199,251,366,169,1,118,1,173,1,112,153,1,85,1,503,1,1,9,1,1,1,1,1,52,159,1,111,229,144,1,54,74,1,307,1,1,18,1,1,1,1,1,1,1,1,1,1,82,1,1,340,78,1,30,1,1,1,324,24,20,1,191,306,73,97,1,331,343,1,88,1,1,114,1,266,71,97,40,56,391,1,1,309,64,399,1,56,1,769,1,1,1,1,1,1,1,1,69,1,6,29,1,1,1,18,1,1,1,804,1,213,271,208,32,1,468,38,1,1,1,1,1,193,1,1,1,34,419,35,1,1,52,1,1,1,2,1,78,1,393,5,17,1,1,264,211,7,1,1,1,1,1,163,211,78,1,1,603,8,91,240,370,729,1,235,1,1,230,43,28,1,1,269,32,45,265,14,7,1,1,260,1,1,1,239,87,269,1,53,77,1,1,87,259,384,1,1,1,110,449,10,1,1,1,103,1,1,335,1,87,1,1,1,695,31,1,242,147,667,1,154,1,59,497,1,6,444,122,87,1,1,8,1,1,73,1,1,98,1,1,1,1,1,1,170,160,87,1,417,194,1,1,469,1,75,1,366,127,1,8,88,1,1,1,256,89,1,1,13,1,1,183,1,1,1,1,1,79,1,1,41,1,1,1,1,1,1,1,25,1,1,1,1,1,215,1,1,279,287,64,4,1,12,40,1,350,114,233,1,120,1,1,1,1,1,7,1,1,1,1,149,1,1,1,1,126,51,141,352,1,1,47,1,1,1,2,153,162,63,1,1,1,1,216,1,1,39,1,270,1,1,1,1,1,28,57,1,279,1,2,229,235,19,1,32,131,33,1,208,1,1,8,702,1,1,295,24,1,69,7,39,1,1,257,301,1,1,1,18,1,1,137,1,1,799,1,1,1,1,102,78,1,1,1,71,1,1,12,1,373,70,366,190,1,64,27,1,1,242,228,95,1,159,1,379,1,1,1,1,1,236,1,1,51,1,1,1,408,202,280,69,1,1,1,1,1,114,79,24,1,101,1,19,248,1,1,1,1,1,375,170,1,1,61,234,84,1,27,68,117,1,23,170,498,1,28,78,11,39,1,337,1,1,256,51,10,179,78,96,20,1,10,1,97,4,109,110,1,1,73,1,83,2,109,1,4,1,64,1,315,1,1,1,1,1,1,1,40,1,1,1,516,253,1,8,32,1,224,8,1,1,160,123,1,1,580,1,1,92,367,1,375,85,60,36,1,148,1,158,20,1,1,23,346,1,350,103,207,51,1,1,1,1,1,9,340,53,19,246,203,1,52,219,1,77,1,37,1,326,1,83,12,1,1,1,1,25,240,50,1,13,455,214,34,1,193,1,1,1,1,1,92,459,1,122,1,1,66,1,1,42,313,15,94,1,197,1,173,1,1,1,1,45,273,31,1,26,1,1,1,273,399,586,1,414,5,101,1,80,1,200,94,1,202,493,1,138,1,1,49,1,242,1,62,213,1,181,76,1,131,1,1,131,143,1,17,1,136,1,1,207,67,188,191,1,81,113,311,1,1,1,1,320,1,1,118,1,1,27,1,1,303,1,1,85,1,1,1,27,1,155,69,1,28,69,70,85,90,134,1,1,266,1,8,1,76,1,181,1,1,321,1,231,177,390,9,1,1,1,1,72,1,1,198,1,119,1,330,1,13,1,1,1,271,1,22,1,148,245,169,4,72,11,1,238,241,2,3,65,1,1,172,1,187,97,1,184,1,152,61,1,97,1,22,115,1,1,1,10,1,275,1,119,8,1,1,30,416,1,1,1,3,240,229,1,55,171,219,1,1,1,386,171,1,49,1,1,1,248,1,1,6,1,1,148,1,105,1,1,265,916,43,44,163,64,26,1,184,1,386,1,1,23,336,242,104,1,66,1,46,1,335,1,1,1,1,1,1,7,1,1,9,442,18,1,1,415,23,44,1,201,1,54,1,619,1,1,29,470,76,1,1,1,48,528,1,1,1,1,49,51,379,1,1,1,1,2,1,1,1,224,45,1,213,229,419,80,1,318,244,17,257,340,196,15,1,168,142,1,44,1,236,250,14,1,1,1,71,371,178,132,1,1,39,1,1,204,1,5,1,167,529,1,94,1,62,1,381,40,138,1,1,1,1,1,12,1,1,234,132,1,131,1,178,251,50,563,1,1,1,99,88,3,1,83,210,1,102,1,1,1,144,1,91,16,258,1,38,1,41,20,1,1,1,194,9,103,1,1,1,213,80,1,1,81,91,107,137,9,1,49,29,84,241,1,1,11,1,102,1,32,206,1,136,221,1,1,166,1,35,148,8,228,178,1,1,1,140,1,1,106,23,9,1,392,23,1,1,175,1,1,1,1,1,1,53,1,1,1,746,1,114,1,431,1,78,1,191,1,50,45,1,1,1,110,180,1,1,1,1,124,33,1,1,34,11,938,13,31,1,138,44,9,1,47,1,2,1,89,145,162,951,212,1,135,203,185,170,65,277,1,619,1,1,146,140,42,189,1,1,63,1,1,1,388,31,1,190,215,136,1,1,1,1,115,64,136,1,1,75,1,1,355,1,1,1,144,108,41,1,22,63,206,362,222,1,1,554,1,1,1,39,18,1,227,1,162,88,1,1,83,6,1,1,1,315,1,1,182,131,1,1,149,72,51,1,75,220,1,101,1,221,1,480,192,67,36,132,1,1,1,105,106,1,63,1,183,204,1,264,1,1,1,93,244,1,212,1,1,1,210,1,1}; +__attribute__((section(".data"))) sh_uint64 test_pez_physical_alloc[4000]={519,1384,774,400,1623,1236,1183,1213,1792,1915,1069,245,3,1105,1742,745,1519,1633,156,1367,1615,733,91,551,481,1398,51,633,1537,1710,1063,974,1103,864,847,1502,1206,1189,1757,577,1559,619,456,1256,1220,1652,562,1986,448,670,1067,1293,1781,1276,1560,1916,1675,1329,21,1101,1039,1725,35,572,832,1871,1536,820,724,1976,1486,16,1226,137,907,651,311,992,1371,697,30,1280,809,1834,934,1849,1910,389,224,828,941,1256,1099,1310,1116,607,1813,775,1621,1553,425,1282,1165,319,1452,384,128,312,1130,1904,1661,1356,110,538,1806,1982,379,273,975,1248,1002,498,1375,463,667,718,873,953,606,194,210,942,389,1264,243,1903,1851,853,1566,1133,961,441,201,1529,1744,1867,1991,1965,166,1805,36,1189,1045,504,783,209,1968,1210,90,1012,1703,597,694,226,1607,431,639,588,1285,864,1524,1050,1900,25,1435,1455,1399,1142,868,231,1450,923,623,1349,127,972,1011,542,678,1212,307,1558,1605,1750,1170,1991,1111,1335,1488,1760,1520,1827,971,793,1915,1422,1815,1113,1228,1880,1848,874,1826,1177,421,695,1981,364,358,202,1794,1022,113,206,1738,157,891,1926,1092,1711,330,274,495,1586,1449,1533,1184,1136,1607,362,530,1894,1572,623,1299,333,252,1749,487,936,165,1411,17,1748,1418,990,1526,1600,1062,1032,135,239,130,250,1872,613,691,579,1659,1362,57,167,1476,1453,1202,1644,1358,1699,1887,58,220,714,752,1780,938,1480,1735,904,708,1773,1091,883,1594,1767,26,1286,1412,709,1465,133,1509,987,681,1853,476,696,240,557,1939,1108,1352,605,1406,459,415,809,1639,1590,192,170,1203,1935,1770,1229,569,1235,934,1137,983,1323,949,788,1515,1403,861,880,174,707,658,1420,1246,1617,474,1171,1497,1060,773,1518,890,403,618,1498,408,1719,1243,811,1117,1934,1102,789,591,1480,966,1878,96,1231,1697,17,661,681,392,958,131,1954,323,588,906,799,532,699,400,1767,246,460,1051,5,192,179,843,1578,600,1857,1305,1405,599,964,1885,1636,586,1438,1438,126,744,249,741,1088,966,841,395,1004,139,660,116,1578,1492,944,697,1518,1040,1196,734,1128,82,733,1695,1990,1024,534,1156,1686,252,1541,484,4,983,1946,34,552,243,1916,322,913,1982,735,380,421,1715,1052,1947,1034,1534,685,313,212,1430,1080,105,721,1058,1287,1574,1849,1148,1314,278,702,29,1363,948,1176,1842,1989,749,488,1055,1172,1406,687,1207,270,804,1393,49,1029,484,1538,1618,334,1152,134,1451,1954,827,427,332,1127,146,1470,1527,696,326,220,1262,1277,1472,766,1680,1643,824,1998,303,727,1015,890,1547,1147,1222,1223,700,511,1672,1119,1067,652,614,994,559,1284,1264,1630,1716,1022,1015,1535,395,1964,825,1362,1620,1429,957,1919,422,1341,571,1629,1044,1395,914,1800,1804,1815,1845,698,1075,14,557,1957,496,277,1808,758,824,1513,1791,807,1170,379,78,1424,1294,403,932,661,1969,1819,79,1638,101,1467,1393,668,1839,1657,181,377,1754,892,1065,213,1185,1975,1138,768,1948,1148,416,706,442,39,1131,1121,1315,1248,1070,114,1461,1184,1377,203,919,1571,814,562,396,1290,242,1239,1883,1772,917,1198,1462,533,1946,1525,102,556,18,1283,812,404,0,616,1417,269,396,1626,182,1530,1034,294,558,1641,792,1178,1725,20,1202,503,1619,1864,941,1847,605,786,1296,906,545,1644,1713,56,802,152,1795,1663,200,142,866,54,988,810,1949,1428,1115,345,270,1476,1269,1570,245,430,325,1560,1835,565,1937,38,1850,645,320,1868,1713,798,916,1993,863,511,512,1594,1595,517,46,1573,539,903,1303,1245,233,1771,1937,1205,164,1138,1585,1023,1206,457,1131,653,1322,1443,1961,556,168,359,1599,935,764,729,1540,599,1972,483,989,155,1419,131,185,1908,94,1542,1571,967,543,1387,1520,1983,794,1263,370,37,38,1875,1743,656,263,304,738,1740,89,1074,317,657,1190,1685,1474,343,1365,640,1545,994,1852,254,75,1598,42,1888,1938,1579,1582,1877,1334,1610,1646,118,712,583,1137,1711,201,573,563,1905,1818,1018,1961,1328,883,1656,91,1990,182,1992,69,90,1146,902,1677,1648,777,944,1311,1241,485,586,791,1352,1328,610,1359,1104,587,1575,339,1823,933,826,784,955,136,183,846,1679,496,1226,609,1844,1095,1333,272,22,1157,1130,1690,1955,1912,276,548,1152,1825,699,1658,1608,48,970,1618,1718,684,1945,1784,1754,1087,466,1591,193,269,289,70,103,449,59,965,1309,603,223,283,1592,649,1976,917,237,27,521,907,1795,1404,566,438,402,4,514,780,1788,858,1383,262,711,1987,259,1846,1855,857,1255,1635,301,1574,823,49,411,1149,506,1134,1228,290,856,1319,288,627,324,101,324,969,455,1481,1110,275,139,257,32,1068,1197,1376,1312,486,1797,1947,1289,1690,424,1185,1837,13,598,1587,1714,1874,1478,638,341,361,1564,398,1911,844,1760,53,1576,1584,231,1102,248,1933,398,303,1545,800,1157,68,655,574,536,172,1902,1679,1304,635,842,1614,163,277,719,1774,1292,825,299,939,251,1469,715,1392,830,1516,1050,713,1365,803,780,1752,430,1514,1046,1684,1329,1361,1394,72,341,388,24,136,129,1325,1726,896,217,1820,803,1078,1762,881,1212,602,523,636,5,860,1056,900,1081,500,1153,200,351,62,1344,1409,284,1989,769,1487,910,597,776,106,1203,867,1038,1208,1135,1543,687,1490,291,1677,1020,371,1821,1661,43,1296,1886,1544,1705,1642,360,486,1634,555,1741,750,1593,1867,1993,63,1450,859,229,612,1633,902,1445,779,184,1308,1158,732,1004,433,25,171,672,986,976,931,872,60,601,1011,390,549,1866,1866,1478,455,846,879,1838,1146,1169,1053,1755,1413,1548,1066,1200,956,524,1659,1318,596,1412,177,1790,1883,566,968,1084,1979,1647,1058,1395,1796,133,454,1122,1626,771,1983,1664,1392,734,313,1042,1970,763,862,215,373,1356,65,1292,1,731,40,1987,1739,929,154,1235,1211,41,1466,675,235,639,120,1701,149,1027,767,1941,1996,1411,871,85,329,420,260,871,1527,750,1511,1555,1775,67,151,19,1920,1071,1758,1236,1402,516,1599,1656,1721,1376,1509,429,1219,575,1180,14,1103,629,175,1951,974,1391,1635,851,578,884,464,1440,1485,1577,910,1354,236,1537,1483,344,1396,951,1898,1647,334,1458,505,1552,268,625,646,47,1919,833,1897,1224,117,1379,1468,223,1327,670,88,1577,657,1341,927,482,1809,81,1748,531,429,970,1506,1778,1238,180,553,1455,931,1186,866,1756,1808,173,979,1498,869,234,1164,1966,113,600,1572,119,212,320,903,1030,308,1280,886,884,1561,1471,801,321,1778,1380,1668,922,1784,1768,1026,861,1696,761,349,877,507,669,779,1720,1505,782,1233,640,1619,720,1471,1671,97,1076,1724,1162,1156,1346,1802,799,1536,52,901,1507,1191,1154,915,1874,748,1896,1441,1680,942,1106,238,1386,1388,12,725,1940,118,1062,622,536,534,153,1921,309,1611,1506,1755,376,1787,664,165,258,1522,1049,1786,1666,652,881,1083,449,1033,399,989,757,199,1002,187,710,1843,1967,1014,468,197,256,184,1575,318,1133,1001,244,1942,196,1013,1538,1372,691,937,770,1460,625,195,1823,1085,1682,1796,1479,835,199,1283,1431,456,925,1917,567,1793,1125,1622,795,1289,1434,1879,1368,214,1204,842,963,171,1119,1696,363,134,423,368,1519,16,256,1604,1569,491,1971,1484,1030,189,1893,526,1140,237,498,176,342,219,1385,206,264,1816,1979,899,990,1743,1295,142,693,752,1824,648,591,815,1834,1535,1616,1785,1460,1500,1271,1101,1692,15,119,1061,1789,570,485,1403,1593,1284,48,993,649,1854,812,1700,80,1847,301,1972,995,962,1840,1742,1447,1789,1493,778,1958,516,1609,314,492,296,151,107,147,637,413,1660,259,1681,783,55,816,1546,1512,726,1423,829,1269,878,823,1211,1501,830,686,611,152,1458,1005,1336,1443,188,1359,125,1625,1174,30,1811,1800,480,1908,1985,1031,987,587,316,1016,521,1622,285,354,634,73,427,1707,219,666,1216,590,507,1557,793,433,680,712,222,1693,726,1260,186,1337,1539,1258,772,1521,980,792,1080,1479,1728,1873,1669,819,472,406,1889,250,55,141,432,1974,1445,1892,74,731,1019,1059,1252,873,74,114,1117,412,1201,436,1118,1271,1980,877,1360,1569,339,1935,278,1093,1472,746,796,758,1902,1079,1617,1260,257,837,595,1875,1906,1378,440,115,1043,481,953,144,494,1714,300,1611,1387,973,529,1187,1306,665,839,855,1695,1841,790,281,32,1218,1674,383,1417,1746,459,1613,26,1812,50,638,1733,543,1753,1854,1303,489,125,1491,711,1771,1390,663,737,1400,327,1851,261,314,355,1623,850,1217,1885,1374,1651,160,487,965,674,1099,169,682,1234,1595,356,1285,1340,254,347,1807,1705,1350,1918,158,1759,1638,86,590,515,1391,1583,1135,1499,895,1624,658,1279,1044,524,1689,157,1881,1338,762,1355,1124,1426,853,506,1652,1295,1882,98,1501,1257,1431,1442,940,161,1242,904,1118,291,1959,307,1026,465,1558,1097,1894,1541,1553,1782,475,1736,471,1829,717,1000,1857,1563,1201,1020,333,1531,1583,160,51,126,1097,168,1193,1967,1109,804,1198,493,963,59,367,651,346,1901,817,434,285,282,360,1316,637,868,328,1932,210,33,1892,1098,1214,959,50,584,1369,1014,1035,1603,438,288,1783,1831,1310,350,410,745,1489,416,889,207,1891,1151,87,419,477,1884,1147,44,386,860,1350,1232,1366,663,394,1588,194,202,808,742,1018,222,746,1870,854,1914,1723,885,585,1918,1860,1227,818,979,1642,635,1191,495,191,956,1930,45,991,1963,1881,525,834,65,1098,316,280,641,735,1745,234,1307,1482,1625,1369,546,323,1037,342,960,1528,326,930,615,374,1194,1615,1643,1582,1957,753,1756,921,331,1251,1244,1632,1732,1301,329,976,1985,36,1773,526,1768,401,542,1764,225,1720,47,105,1515,568,1233,302,336,445,1863,143,366,1404,998,1559,1074,190,1134,1121,190,578,1848,1870,856,71,34,236,594,945,76,1737,1492,197,911,1127,1364,1859,1825,1343,1077,1549,880,1924,1389,1054,724,501,1267,975,1105,555,1776,1662,198,1676,1510,1931,290,1491,1007,478,728,1181,1086,1166,1076,1120,1688,926,448,950,656,769,1959,1910,1689,287,1897,1628,1490,286,1978,414,1864,1665,849,1513,550,888,1225,813,144,1986,453,716,428,1822,1397,1344,123,1963,1107,621,1267,1775,1209,241,1951,8,1488,1712,747,1667,1956,77,72,576,1681,1123,1670,1408,589,347,489,1464,1390,1503,1942,999,1293,372,470,406,1054,67,1457,1195,1691,1440,1702,653,388,603,1010,1980,1351,140,893,1384,1765,762,497,387,1890,1712,1964,452,1128,120,1973,1347,1921,1266,1579,1871,442,130,797,1772,469,355,1089,415,1763,149,668,1698,124,1371,784,570,503,1029,1190,1528,141,94,807,946,840,1779,265,1532,774,1903,378,669,984,528,1312,1552,1529,1237,772,1426,409,97,1565,835,1723,554,698,368,1314,1880,1671,1452,1913,919,806,538,1265,1221,662,675,559,761,1938,1508,1433,686,419,1416,1508,1570,1722,1649,1159,232,1734,310,920,1838,897,1252,1142,1402,1021,1676,1204,1192,1827,332,650,138,365,296,943,879,999,1114,170,1699,1596,1155,1965,584,1072,1584,756,1735,535,1512,1544,1724,1556,632,1249,246,805,1224,300,1868,1077,1672,997,1640,836,471,1418,401,292,1590,180,1463,100,828,439,1401,1336,580,1655,1557,1812,701,454,1251,1330,1971,1246,1245,688,405,3,1386,1353,1573,509,1893,1268,1568,1394,832,366,729,1149,680,571,1400,1710,1040,1782,971,1716,132,148,743,306,928,1487,1956,819,1107,982,1425,1826,315,755,1266,1604,1140,475,949,1662,1401,1273,208,1153,1301,765,1243,1777,615,1218,1974,854,1010,1436,1169,175,62,527,1005,1861,178,1860,1370,1265,1936,1306,1913,450,174,1539,281,719,393,1168,1839,1274,261,1342,492,386,1139,1434,384,1477,1828,1475,1046,1007,795,1255,1012,841,775,1548,1747,1794,1984,1459,1801,57,1927,581,1069,925,369,1373,464,271,88,1057,1729,1320,138,1360,15,1045,550,211,560,721,1804,224,1113,1199,1790,117,939,426,1752,420,1237,1375,1453,161,1694,1144,230,897,1586,228,392,60,44,1895,9,177,490,644,1277,390,1410,1115,1547,998,748,1056,1507,791,1227,1087,1988,1422,387,633,123,922,172,981,1307,1094,1994,1925,1240,1999,98,28,1423,1001,626,424,1349,477,962,929,631,1704,308,1966,135,1381,327,643,1496,1009,1270,1962,167,708,1304,1175,1850,631,309,967,1928,1943,722,940,1945,647,608,520,1878,627,23,1998,537,978,357,1270,251,1608,1960,540,1777,1415,682,1955,870,1994,217,191,855,1764,1901,1273,923,340,343,109,330,1645,1776,514,689,365,444,717,1008,1655,1111,624,692,1229,992,499,286,6,382,305,467,933,493,811,527,1888,1019,671,31,1709,1217,1259,1006,659,357,629,80,1053,751,850,848,1486,747,1683,1250,1824,193,413,293,673,520,121,417,385,512,337,760,61,1698,1249,523,1758,156,361,1345,764,1347,1900,1448,68,565,778,1335,370,1041,1083,230,1027,1494,11,1449,1667,1090,1473,589,435,1759,513,1882,1969,1610,1832,738,225,1670,479,159,1346,1353,1297,1514,1640,1025,912,1398,759,1550,1036,1523,935,688,1230,957,977,216,179,1923,1091,1613,1057,106,1899,1899,547,628,1898,914,458,213,1781,1872,1461,1368,1477,494,240,705,834,418,646,1737,592,865,901,451,1564,628,353,1630,1465,1819,593,100,617,169,228,1806,1385,1580,1562,297,412,851,1844,613,1016,452,1433,335,1254,665,782,969,1651,1831,463,292,1437,1345,755,1650,93,1658,1093,1542,1952,1006,336,1231,0,898,110,1043,1017,348,765,22,1317,1805,154,1709,1193,1678,295,96,1382,1104,1064,1757,725,501,1923,1904,1288,831,1721,552,1268,1731,797,705,551,1481,1653,574,1627,1650,1247,598,1150,417,1166,510,1332,679,99,1922,1816,1075,1704,103,863,1116,207,1351,233,564,447,1842,1683,988,1071,1021,1382,1473,905,1597,1317,1701,1281,806,1429,736,525,1807,642,1717,107,1323,1457,315,181,845,488,1747,1041,671,858,580,1616,814,208,900,1262,1321,508,730,576,1297,116,1315,1637,1953,1511,714,1988,87,1230,1174,1663,1326,1064,1333,1606,1762,1469,744,1459,1828,822,150,876,961,1502,1219,1261,1305,620,1428,1464,1126,1055,1779,905,946,1432,1084,1523,1221,461,188,1526,936,21,1298,1162,1717,654,985,185,642,1783,1692,899,647,375,602,1195,1177,1907,773,1272,364,707,889,1750,539,1320,701,737,798,235,955,319,1199,287,478,121,875,715,41,140,462,1687,1161,882,677,1324,932,1645,1997,1621,1421,27,1550,1172,75,434,938,704,1435,1601,575,1728,1702,1830,1374,1192,431,1363,1416,676,85,568,1556,1456,630,1591,1600,1853,9,1208,196,1624,1409,1109,781,1612,690,1338,173,790,513,260,1685,183,673,1145,753,518,838,1325,1253,1922,195,1859,840,490,1342,1207,1930,595,1413,1439,1769,1377,1160,959,1943,1632,1863,1337,1253,276,517,1629,1484,445,1035,827,573,870,519,894,732,743,352,1534,1785,1744,1944,1886,211,53,684,311,1474,1188,909,216,984,1463,111,849,227,1060,1727,1200,1225,1042,554,1962,1940,918,1279,1925,1112,1731,703,945,1631,491,912,33,740,1605,1719,1912,1504,1106,1444,143,1549,54,785,104,1009,1606,739,122,153,397,1407,408,1122,1877,730,837,1751,1326,353,1906,981,1746,1917,1151,704,338,128,1697,469,1933,927,1085,621,1129,1729,1905,1873,1126,155,958,655,348,1291,1013,709,604,937,581,189,888,1048,1180,1646,1950,1331,742,473,1357,702,1470,847,410,887,422,515,1051,325,1732,58,2,952,1308,1388,1531,1879,1145,1389,1813,1144,911,83,950,886,1995,872,148,1313,1173,1798,1036,164,1687,1167,1032,1186,1114,1733,1856,1033,561,1941,1682,751,414,1430,867,756,23,926,443,93,896,63,337,242,1741,1810,1220,1414,391,92,716,548,345,1358,973,1047,187,73,844,381,1603,227,1159,643,728,1079,359,862,18,685,1163,1500,367,1718,594,446,692,1706,145,1688,1161,985,1454,322,1210,1205,1319,112,381,560,787,606,1023,1820,1215,1155,1213,377,505,1089,898,2,436,788,997,619,710,1936,991,1410,1467,502,1654,1357,1372,267,1396,1181,592,253,317,757,826,1240,1581,522,56,982,1660,284,876,1216,1298,1887,450,1327,302,839,895,465,1141,1100,1589,789,1003,947,608,1419,766,124,1876,473,1132,700,785,1407,582,1977,1597,972,544,1494,537,1673,1068,1232,1454,1070,294,24,1929,1321,1981,1865,407,1832,70,1380,1025,255,1525,1468,754,132,1065,249,264,474,612,64,253,1592,115,1736,1078,781,1287,1793,1263,1822,393,1150,1601,1424,1749,683,561,1691,437,1322,372,878,272,508,84,667,1703,1833,1164,674,1891,817,843,611,1408,1313,1684,1817,1648,66,1780,205,439,617,306,1316,1037,19,810,1059,1173,920,831,1038,1039,502,531,1517,723,350,1049,1446,470,232,1840,1566,1340,1810,614,1909,458,547,563,399,466,1707,64,1291,951,145,1250,1378,283,1436,1123,1275,1675,1063,553,1242,214,1654,741,186,1257,1278,1673,238,694,1836,95,432,147,266,247,289,52,352,1331,567,127,1003,1008,209,1222,66,404,1179,1072,1562,1970,1132,1861,239,441,626,1765,1446,1678,162,1504,915,282,545,1530,99,1302,89,869,1139,108,1770,1136,996,1456,1926,1745,279,349,1300,1589,977,499,776,312,435,1876,1281,1482,37,1551,924,1841,472,305,1598,1952,263,1975,1567,650,275,1907,79,1299,28,1540,1924,81,964,340,768,885,405,1276,1254,1090,1332,1715,218,1334,304,375,1576,295,43,1920,102,1950,1258,1499,500,1017,266,636,71,1911,111,1427,328,1110,609,767,1546,457,677,954,723,1726,1636,1932,1420,378,1165,407,993,1763,1669,1215,777,1929,801,10,1814,796,754,1543,363,483,771,727,759,1927,1318,218,344,874,693,1516,351,1364,1730,1290,1124,1634,909,293,476,8,1496,930,662,1143,1889,1686,1960,535,891,1801,644,1855,1167,703,1171,1082,1811,1674,1627,1852,1895,1141,241,1995,564,630,425,893,528,1086,1814,579,948,159,338,821,1278,1649,215,1302,924,1381,604,1282,166,446,1799,1821,1168,244,749,818,1324,1379,1288,1176,1444,7,1809,1096,1934,205,722,1727,624,1666,129,518,529,1708,1521,255,298,1602,852,1884,1769,1568,1510,394,1294,986,460,659,1497,1179,1928,1612,335,1503,582,479,1339,1563,996,1739,648,468,1489,1628,820,829,660,641,1196,1973,1399,1977,530,299,1442,540,1096,443,104,346,894,1441,397,1555,268,1997,409,273,1803,1311,770,221,356,672,1914,980,77,221,1028,1129,391,1,76,198,1088,1551,1837,833,679,383,1120,1751,802,1517,1862,666,1693,1348,95,369,1641,1896,1944,1175,821,108,541,1774,137,86,1817,607,204,1639,61,1786,373,1858,1466,618,258,763,35,1614,1554,1047,1397,689,1495,1984,380,1602,428,40,1978,298,610,1818,713,20,1788,1214,928,913,572,163,1567,739,1274,480,1339,29,882,1425,247,321,1797,916,892,1373,1052,836,852,509,1846,632,1405,522,1000,1272,362,437,541,122,921,808,78,1073,1580,1761,203,952,859,1588,453,1830,1694,1708,1197,504,1163,805,109,1766,1738,426,1415,447,1367,1448,1581,1355,1843,92,1637,248,13,69,908,1554,1241,740,1031,1187,204,736,1421,683,331,1596,162,1992,1414,1565,46,1209,1653,558,676,1953,1856,1286,1999,1734,1061,1505,546,176,385,815,444,1259,1094,1485,482,1532,1561,1439,1620,297,39,720,947,1447,112,1493,1183,1081,544,1753,158,838,1275,1524,532,760,1585,1462,1958,1082,11,146,31,1348,1791,918,695,978,1024,848,718,45,451,1865,418,1668,84,271,467,634,1802,1066,1361,1437,787,1247,800,1587,1931,374,382,1354,310,7,822,1194,1223,1862,1761,423,1366,1869,1370,887,267,954,1383,1234,1799,82,6,1722,995,1178,83,1244,1948,865,960,1108,1238,1427,358,664,42,943,816,622,1968,1188,569,274,150,1182,280,1451,226,813,1664,577,875,845,908,1125,1522,1631,402,1154,262,1858,376,583,1665,645,1073,593,1432,1330,411,1766,794,1495,1706,354,1300,1890,229,1740,1095,1657,1483,178,678,1309,265,371,1028,1475,10,1835,786,549,462,1845,690,461,1160,1112,1803,1158,1836,706,601,1261,1939,1143,654,585,497,1949,440,620,1833,616,1798,510,968,596,1182,1609,1869,1829,857,1100,1700,1996,1730,279,1343,533,1533,1048,1909,1787,12,318,1092,1239,1792}; +#endif diff --git a/shelter/lib/include/kernel/tests/payloads/test_radix_payload.h b/shelter/lib/include/kernel/tests/payloads/test_radix_payload.h new file mode 100644 index 0000000..b651a93 --- /dev/null +++ b/shelter/lib/include/kernel/tests/payloads/test_radix_payload.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MPL-2.0 +// This file contain the values to use as keys, values and search for the benchmarks of the radix trees subsystem +// It's autogenerated by tools/generator/radix_tree_payload_gen.py +// Copy the output of this script in this file to regenerate it. +#ifndef SH_LIB_PAYLOADS_TEST_RADIX +#define SH_LIB_PAYLOADS_TEST_RADIX +#include "std/type.h" +__attribute__((section(".data"))) sh_uint64 test_keys[10000]={0xC81CD89C6FAC66D3,0x3CBF1F7B8EDEBABD,0xB79AECFEDEF90B24,0xE76366561710CA51,0x2FADFAB73C58D6F3,0xC873327F1C896D55,0xE9F34ED693B90AE9,0xE714A9E2F82C2770,0xB16288A7036B5D0B,0xE6F0D852B39CA44D,0xD4059A56DB852E8F,0x7720E7C19785718D,0x289CDCF14EE94182,0xE3A7EBAD741F6972,0xB0E3EA982C4C0065,0x72B57865C02D3176,0x8D6F6B85AD3E2CAE,0xA8163AA83A1DB6CB,0x42A6ED27D770C643,0x84D57ED3FB76463F,0x305EBB5377667067,0x3D3F989196270DE5,0x01FA121FAA7304B4,0xC0C2D94B715D4853,0x515F3BC370E2B647,0x9623538F7DE7F573,0x5DE07D4747D6EE81,0x2BEFEEAAE10C1D06,0xCBD2E7844F6A1753,0xE22E10A798A611BB,0x03F5F4FE4C84242C,0xC405E3FD95693DA8,0x0FF1B167C821A044,0x06DAE07B6F9EF8FC,0x11DBD98500C180F7,0xA5A184165EA8B29E,0x4133DB58DA9A9FEA,0x2694F202AEDEBA56,0x6018A2DEE1D2955E,0xC9BC1FE18976DD6B,0xA08C326E5EF85976,0x5DC9B1A5F73E0187,0x50FA95A71C6F1245,0x45A906EAECEABCAA,0x488F87E7F9D9B442,0x6D1D85C44962826D,0xCC92075201C17425,0x89BDCD05E8B984B1,0xD7FAEB3423700009,0xC6E6C48CCDFFA563,0x1819DB17BF52EEF3,0x6EEA435C05A41B83,0xA7F065E0A35203C6,0x6F791BFCC560187F,0x9616514F451E8C57,0x410A9839BF2923F8,0x07E1BB4FCA0C3423,0xB2C9679598E76A52,0xAB42DAC61D084D8D,0x03FDA336ED9DD210,0x133A7CC37C68FEC9,0xD093FEB837374199,0x339E6591BE12CF32,0xB07AFBE466ABD389,0x0F3E14BB68A50ED0,0x91CF2A0AEE0324BC,0x2DBD906EC341907F,0xDDB7E9F756895C36,0x9CE6A56BA7CD6209,0x7C95C7ABD378EEE0,0x710AC2B02FC92D07,0xFE236880CDD75D8F,0x8F489AE3BA78374D,0x3BA2EF91B721A56E,0x549CD3CD3EEE3F5C,0x1FA9D245E473226C,0x2DA00A91A8CC9270,0x27770BB94F7A7A81,0xAE4554ED9594EC55,0x950ACBD032F428DA,0x1C8345476F6F343C,0x5E5372E410A79889,0x2B31CEE295342273,0xFC75E19959393312,0x1B580B68BEA9215F,0x75BFE77CC062D179,0x0C246058FE626D6B,0x1EC882EA410E8772,0x5426458926A0ED44,0x85DA1086D66E1423,0x71AAB738591FA4E4,0x552827A51FC7DD26,0xB83A541F10B4DF7C,0x70B04E51488A4467,0x6550CCA6EC081364,0xCB3FCF761DFD97DF,0x12C6B52D3B2F8B50,0xA3FC456A8648C500,0x4D7951A98A3216F8,0x39E2D5F211A0B2F1,0x9ADB56E46C80C016,0xEB67614F1D7FA964,0x8CF68F7424CB0CB5,0x0E94331564B1FD4C,0x4331C703BDF578D4,0x3014B81254C538DD,0xD5437D1FC44A75DF,0x66DE43610C37CDD4,0x8745B77D8E48BCB7,0x4452EE4B9B4DE3AF,0x49C11D5126943BE6,0xFE7EEF53DC82D37A,0xD0D895ECE132DF70,0xB66D9281E1662A17,0xA9B1D475DC5205A8,0x444FED93A6429C80,0xAA16D93A1C1E0626,0xEC818C923E4D3B55,0xB15431866FBED7B0,0x7305DAE84FCAF360,0x673976F89BAD2F3A,0xCF567A377CB343CF,0xD5B13A0BAE15D23E,0x767FEDE8E5EC4C78,0x4A72F7F00BDCAD05,0x9B27386D0349E33D,0xEF18E248160A9DCE,0x25B7B37442E2A92C,0xB718FA15734A8834,0x09CA9084D5DF0871,0x5889B3C0341DE839,0xA79FAAA99153FFC3,0xC5D3905047C4A347,0x32C6678E4EE1C5CA,0x4E80FF629CA1BA21,0x9B1387C0FB3964BC,0x8EB9823A1EA1F326,0x4E3D189337AE87AF,0x2EDA49909290165A,0xC8F9DA08CAED9798,0x33798A36AEE2F33C,0xC7F0BDC730B2CAEE,0x7308EB9879019E8F,0x07B2988692613073,0x40CD9E3830628409,0x463DF845934EFC15,0x2BB0C9D55E33FD4A,0xD56FEAF16BB0F986,0xC5A74F754619C3A3,0x209AFEAF299227CC,0x284A725593B45AC6,0x51E83A68FB496214,0x4C87296BB2CFECFB,0xC98F4B685468BC9A,0x955B2AF4844A9416,0xA57C13A154BBA927,0xBE97F7EC221C68A3,0x01715BE204494B8F,0x74655FE05D290BA2,0x185B5799C891B405,0x54E9558E8CD13285,0xBEE10DE6EEC18012,0x31284DB0A59CD09C,0x5C87B2A0F6D2D88B,0x12B728899EE1CE6F,0x459DDA0F1F26716E,0x1E147D24FF58715A,0xF2AFE3CB0B03CB01,0xADB6825CCE03D006,0x0036712A7E353332,0xF680E881F294F524,0x8448E94EAA9DBF50,0xFBC6EE1E984EEF84,0xC70A3041D0BEF26C,0x51575912E5CA390A,0x6B7C5FB39CE16BB6,0xF3DEBB5598907CC9,0xA5D50601C498EDC0,0x8DB459CA0BBEF013,0x89162D3636DE07F7,0xA1CD32CF4E3A318E,0x2C8F525BFC695407,0x8B55005AF2BEBDFB,0xA53CCB67C33D6EB2,0xF5B6000296D951A7,0xAEB47B60814A1BE3,0xB07E087406E42D4A,0xDC97D266611ECDEA,0xB11F82FBFE3BFE17,0xF11768DD3DB1514A,0xBACE0F7302AA315C,0x0C5A66ED035989D8,0x3569B30554B331EE,0x87934285C98E9B43,0x208A6EC092775005,0x9DEF64A046BAEE8D,0x8DF5A71036589C85,0x2B125CEB631FD67C,0x2C21B4EA35E2DAF8,0xCB4F954D6F1FA4B7,0x6936AAAE84EBD941,0x03859D8F814C3D09,0xD19C8C1BA66A1303,0x0ADB36D723994C37,0xCA57375BD83A2B5F,0x2AF8BCDC3F95642C,0x084796CA921C6FAA,0xFA70E2BA0C0350A7,0xB4ADFC2C1CCF1366,0xC1CE771641D78E89,0x9C3A19D29156E8CA,0xBC3E57C67F7A12E6,0x7C473217C86E29F8,0x675E56674D6E8131,0x706AB8DF2E040116,0xCA801FE9E199CE86,0x5CE8EC826106D94F,0x17B0F6BF89354E1B,0xED32A2C7FE766A3A,0x25AA794148DF01C0,0x651DA3B3BF6D302F,0xD948D5259C3647A5,0xCA90DEBCF503A70D,0x8048DAB20E4D8A74,0x2F2BBF83EF9880AD,0x697FFBD36BC293C5,0x5EE6A472DDBFC87E,0x06C15BAAF31D5F33,0xC7F857EE13BF097D,0xB80F2F20A14829B1,0x900454D5B8728644,0x51E4AE9E3DD45F22,0xAA02A99E6FBE71FA,0xB2EE5358144126C2,0x8D76BF2BDE2360B9,0xECC02D6B41C9AF9B,0x0A990C4ECDCDA4E2,0x384B01138925E248,0xCF9389A79B3AA77A,0x65D9E11770E09E80,0xE9CE769A389BB897,0xDF41CCD17095DD0B,0x90D798DD6B675253,0x0F8EB668B9772A16,0xF64D1F31734C0A7A,0x4A489CD1A1C3466D,0xCC5328EB5CCFB4BE,0xD1887C0834A4DE8E,0x74B84DF6D0542082,0xAE85CF8C275EC78C,0xAF57DF13BDE2A6DB,0x17757782A6776FE2,0xF65AA03DD63DB7FD,0x04A67CF35A765D40,0x01A21D78264C3FF9,0x709B0D25EBFDE0C7,0xC9B3C97FC30F2080,0xC7F6C2FFE3E119AF,0x8603C3FB03C41153,0x3792EFFC628ED08A,0x2CB7493756C0363D,0xA963BFC653A8ED84,0x22FD4DDDD6290712,0xEA4DBBA831602768,0x4E380210A1BAEF79,0x182E8B06986B0E94,0x83A2318099EB2F80,0x97B7164E28729D04,0x6B720CD9CCE98F3B,0x5832FE09B344065D,0x63EF227A5F292EF6,0x3963F11E63E7B472,0x4AD757AA031CAB41,0x0B186B875C743F64,0x96536BC909509973,0x91FDD0449136E392,0xC40599289054E044,0x3800E4B9ECC10A85,0xD874E9A09A1BE2C2,0x2E0E822982C9BB06,0x73C435EA2D37C5F6,0xB3A5476BE7BACC02,0x72F609FD874901B0,0xB4EC1705E50B8BC8,0x7B785E1F658D9B8F,0x09AF47C273BF7BC8,0x5946F0139D253E78,0x08808FEDFAB63869,0xB7F1F6299C79399E,0x785D0016E3DFD37A,0x55FAC06906A5DDA0,0xBDC2AFB0DA941C1C,0xE35D04E8822231E4,0x7E65B2810D9DD33D,0x03C8F91FD61539D0,0x36D05D6881A28D31,0x4D5496BB2ACB00F9,0x7069D73BA4A20744,0x1760F590FB23F0EF,0x69E0EC1261B254C1,0x9E37606A337E2681,0xB1B52E51F53E722B,0x6855290BDDE0D077,0xEF84C3AAB6FB6A24,0x83EF633F990FE2DE,0x062293684670B9E2,0xDAE72FB672E4D7EF,0xFE8E687C8C9A0C18,0xACAC5B9B43E49964,0x1218ADCCA587D910,0x24A25C8C39CF1E2B,0x2755D88EEA53F625,0x44164F041AC31067,0xDF87E5CFE736A1F6,0xAE34E2BAAD8640E6,0xD50D501A4CACFFD5,0x336EBAF79F9F25C8,0xB6B40B8B1894160A,0x58C02971F9BA7681,0xD5D1C82A4CEEE730,0x409E5F96ED7B6D0B,0xA0C6CB6769106B36,0xDF0010D79043666B,0x14116EDA7164E1BB,0xFCA81983DECFA8CD,0x3F1EE5934A9C4592,0x964D16E27F24DE73,0x436C08E4D90AD3E5,0x0D4AF5090E8D6906,0x75FF5975414A81BA,0x33AEFCDE96A553F2,0xC21776DEA41BCEC0,0x76A4DE0EDFAB3564,0xFF6D5083A38D4416,0x7D496D6F6F703930,0xCAD1636F063C4683,0x80E2DACBD5F155D6,0x9AA72015B09B1F59,0x11CA62AE763DE4DF,0x4D8E298552BB806A,0x0BF50CFB49BF9283,0x680CB249EC5DBC2E,0x5FA8F6F4A952C51E,0x30B9237E1ED5B4B0,0xCE49B51FCBD380F9,0xD52E2A3F148C1383,0x8A26ACC9EF881017,0x4694DAE8D6774AA0,0xEB7B256FBB372443,0x72060A7C78BAB62F,0x5BF80B6C0CC66E4F,0x95D0D1E50ACA3230,0xE1CDB05CBCA13D22,0x4E6CF9FBE4272211,0xDBD6F803033A4B79,0x70B810C4F2A3AF03,0x60A06333C31BD14C,0x23AE506A545DF260,0x60DEB3A2FD009602,0xBA5707055D9EB4E4,0x67C4C62C217E4B0F,0x03AE11B9B38C17E0,0x57A1178FC24D2D65,0x0C045E212871EC15,0x00CB87650CE4BC56,0xD05425D30D1A6C42,0x88660212C2CD6B6D,0x2D8BF73CC381DDC3,0x03A2F451A867948C,0xA8D22E9A692E4922,0x8091FBB82DE252C4,0x7AADFA57030B727C,0x5ED6A0C6A6ADF520,0x585A2E748770D7B1,0x738839D12B818DE9,0x7C4DA3AEC57D7BF7,0x334543D4E04D9D02,0xF8CEF35A8B0FA216,0xE3FD4BA81293317C,0xD59D5F2A3EA370CB,0x4AAEBCFD1CE0C398,0xD9D132D700F19BDD,0x1432B85ADED0251D,0x8372D3D71CC3D138,0xC8B87B88468A84AC,0xA118D5C215377E23,0x4E0486D1CAC10064,0x86E8BD0729D33670,0x92B2CAD0AEE30590,0x760D99B3B1938A03,0xA9783E2B9085FD8D,0x7F9EB3AAC4952BDE,0x32829432CA276E41,0x21E8675313BA55D8,0x227CDA7DB20387C8,0xD038933CC352C0E7,0x918C4C2B0D86FE08,0xF78A2F336B961879,0xBFA5A77AC58487A7,0xCB91E539720B67C8,0x086F58238AD32A9F,0xFEC6F755EB808F94,0xDD747E89222CF54E,0x3B9036D623BABE91,0x8C44390F82C63456,0x7C7A891ACE3E2F91,0x9F9AA91873BFDB0A,0x568C5C21A7AE678F,0x4E2B4C6444ED4ADE,0xC06DAF1AB362DA05,0x45E2DDC9E7BE0949,0x7272D73415FFAC21,0x6ACAB83A2467E54B,0x5E364E0F0DF1CB1B,0x9250DE79340E3468,0xC805E484A70FB3EF,0x5EF136861622726C,0xE1B431C11EDEA569,0x097A38E222C2D305,0x5CB0CC15BA5C2357,0x84B9415CDBD62832,0x1E153AF210D4D8FE,0x3CB6EED5CDF9EA67,0x784DEF91C4F0C20B,0xA7393277BC8BFE9C,0xAF2827C0B7437C9F,0x06BE05E152193E5B,0x4FFF6AAD00C34847,0xDE86D6DD5E7AEE54,0x42800C50C507A432,0xC68F5ED8C0ED8F2C,0x74EE963374723558,0x7D1917FB20F5CB7D,0x47F254ACF5D58D2F,0xC0A66EDC4D369769,0xB9FC7111F0F2B9CC,0x6C89A31B836BD8E9,0x76D935330985ED6F,0xC1D498A6BCDA5771,0xC88FD9E02C7B4143,0xF2C276CC7A9754FA,0x3C2394CAC7F951E2,0x8A1500CB238809ED,0x12A9D820C494D084,0x683ED7A5A64F3187,0xF939315CC5C787D2,0x4A011004B67EDF3E,0xBFDF5C042201AFE7,0xC3975A181822944E,0x8EFD32E8265AEF5E,0x3D846BD293EE498F,0xF8FA0BF8742D5B9B,0xE2B56EB440206037,0xA1A7DB9963B5B444,0x95517C7FD068CFB4,0x4D7329E252B44249,0x0434F2C1C293FD97,0x2F5360FCD55EFF24,0xD7E71736D961ACB7,0xAE76528015FD00A9,0x47B5C1ACDB9B38D9,0x011F3CD1AFA17829,0x5AF2083B86795837,0xECE577B57EC4CBBF,0x45AE8F351CD0A330,0x714D6C1CF3360CCF,0xCE595811DA3426D3,0x9AEA60FE63E2DA3B,0x62BE96B73EFD886C,0x0A35EE8B7FFD0734,0x2A22D00093B57D13,0xC78B39AFF3D2EBA7,0xF084770EB7007CA5,0x42755CCB89F90C95,0x4C78E52010D9B3D7,0x48D415B83B94AFF6,0xA043843FA82F971E,0xC0ABFB2E4BCCA84E,0x794A4168750400ED,0xC828E6ABBFE9BCF1,0xDFF5CAD4F494C050,0x0029B89533C67711,0xE7158603D90FCE9E,0x285F7231F718FA0B,0x29944C4A0B17349A,0x8798A111D1E212F4,0x783C3EBDFC5E52AA,0xED7206956B19F1CE,0xA6BA4CE88EA8A72F,0x42EBCDBF7AFF0C9B,0x6214BC27F92068A1,0x20335EA48924620E,0xF2528F815F6799FA,0x473845E0AA0B89DE,0x08761A91DE7DB264,0x8FB43387AC15E367,0x78CBC5C2D6BA7DE1,0x07DDC64793CDA93B,0x4025D41A1C0B0D34,0xE3FADE4F1805DC07,0x9DD9F90F6C963459,0x7DE6FB219B3C3887,0xDFAE931D8C706C5D,0x8AF0B8666A32A924,0xEF85B130A76CFCE7,0xA15ED2BF66685AB7,0x2066913875DDEB55,0x2EC346230538CE8B,0x9B1802D6B91E7B4F,0x09A14DF42076CE3F,0xA5D13E1E68CB84F2,0x584551A5A9C7B7F3,0x3992C5FA5808DC96,0x33E4D46B26BA02AB,0xFD614B7453686E80,0xBA732A8584AC6029,0x95AD6ED48A328000,0x70BC6C1EBD9C38E5,0x303CE7EFE679B47A,0xD75008510EFB4057,0x24DA4A95B5663968,0xADC30D5E1437F1FB,0x779786BAC64205A3,0xB81E919340D8596E,0xC7C5043A9A2AF3DF,0xE065E02434CEC33D,0x7315D21ADD7E4652,0x3DB8D0855AA00D49,0xADE8CBE53F29071F,0x6B92A15B74C18093,0x86567856AA178545,0x427FFF9490CCD001,0xC4D51B7225DF8F34,0xBFFD568B57CE7EC3,0x894DC5272708271E,0x3E682BE11CE72F7C,0x37BFA62E81A238F9,0xFCF979806DD27A24,0x944CB911DDF74BA5,0x54BA812DCF77403D,0x1D85CDA97C04692B,0xBF62B63AECE6D37C,0x8BD49EC7F2ADD0ED,0xB0B6E659124CD4EA,0xDF47F6E1C5D04320,0xA4A2A9BBA198A9B3,0x371A610CE965F614,0xBFE382C84B727056,0x06E1409BA90F9BCD,0xFBF6B0757CF5676B,0xA6A17783623C64F0,0x279D8163307C05AC,0xA0F9625AD60B7422,0x106557376F8DC927,0xB9A636F93C530FF1,0x3F0C2789E5DBD2CD,0xD6645F95F036E00E,0xF3EA8497F272F604,0xC447CD3DB17A12A2,0x9631D5394FB2FE3B,0x0716B16D7C33D8A7,0x727F2030BD758CE8,0x5F0F886C6A9EC59D,0xB77D0261AC060E09,0x7EF0C944294F48B9,0xA389A142814B7717,0x650F84764AD1B6F7,0x28D272FA4608E240,0x60ED900444C91FDA,0x3CDD84DC8912CB22,0x05FAB13815A14D49,0x892E02DE6ADEC1E4,0x513D21EBA5FEA146,0x7681B52FF2690090,0xE438C1EDA98BD69B,0x2C458C776F4B4505,0x3432C437DE5AC27A,0x52B2A6E0B8F5C378,0x04890E8BA8F585EF,0x6B6826408ED1DD31,0x97955CDFD1DFD809,0x98BFAA3E88466C15,0xFA588A03F0884620,0x8CC7D1FDDF72ACDC,0xE25C6A8178F76D1D,0x4EAAA9D37354253A,0xB4CAA4B566A4DDE6,0x429457D737508D9B,0x511756EFDD675990,0xE631651813102901,0xF4895DC94971F222,0x6B27907865B540FF,0x54E93DA7B99AB5EC,0xDF585B92E07A4296,0x577D6630CA1CFC85,0x33C65994B3636C0F,0x15850A70FFA4486A,0xC0FA54BF6455591E,0xDD0BE906AEA51CF1,0x4F0E1FC90721DE8D,0xDEBD87AB5F52BE7F,0x4D9D035964C19DDC,0x43E982936534B5D8,0xCD1EBBC816CE768F,0xE33A726698CA5EA3,0x06AE8E3E14565D63,0x45DC7C145A767DA4,0x6D110B522B029D13,0xE8E753E96CA780BF,0x6F553F13EE5D8A6D,0x9731CF3C13102547,0x9BC1E7CC232D5CD1,0x8502E149E33A13D1,0x4777282DC829314C,0xF9B1B399D16AF6D7,0x5F982D84BB15E8B3,0x3D5B627864C60CE3,0x958AE5934C8B2904,0x31BA34DC3742A216,0x9B70313598A24B73,0xD346857FBCB4CC02,0x9A5F04E7E7E1C2D1,0x0A43286C72CD5515,0x57E7EF90BDC8C227,0xF364DDDA68CB7784,0x6C2657BED7F492CC,0x7DE34E8DBD591792,0x6C0967B9756CA930,0x7A1CD6616E6EBB5D,0xE741CC7A7219A960,0x44C2427A9B35B2D8,0x620BC9B380686DCE,0x020A171B66CBBEC6,0x987DF0E301C39EA7,0x953B9E173D1116F5,0xB14867CD1A398602,0x8C81902B7A0D6F14,0x9CD8035ECF85A597,0x498E7A69A94E73AD,0x241F6C7962BDC3F9,0x7038CD306D9CEB31,0xD87872594AAFDF22,0xB13314AA814FD3F7,0x5B18DB0BFE1EEFC1,0x07E0373E67F0B548,0xF1F12EE0B5CEB6DB,0x232A94FF093369D0,0xCF78EA17AA5BA12D,0x401AC8CDDF0C4873,0x3F8452921A483145,0x5989DFADCAA66271,0x20A4BA6E3D824C8A,0x0E5A374CEB7F96B3,0xE5CD95A765FDB3CD,0xB25220ABD0B912EC,0x1B3D9737D7FFE4EC,0x202D4781A1C91D0C,0x425E5BF0920D279D,0x6FF065BCFBE26882,0x2968B48969F24DFA,0x830FB9EF253A9EF8,0x87BA11BBD016897F,0x57ED96DCBE39B7F1,0x484A14DEFE64A074,0x49F8BAA95B1ED735,0xF05CB2435F8B69D9,0x8A5CB75E0AD80499,0x1023D7EE3A80E24E,0x9FAB70DE1FCADEE0,0xB6CB4817AC3A7374,0x4F3172709B3C76A1,0xCE0624E4C47DADEC,0xEA09C8F4E3E96351,0x91B47CD50A0E950C,0xFEAD6D6B2D3156C6,0x9BA3F91143D10D50,0x3EE0F403DC7BB1DF,0xF0B1D06F18273729,0x9F28DBF81D3DDCAA,0x530051F3D083D4DE,0x415956844B96D9A1,0x6F15481B5E997099,0x444336762D867479,0xA9E331055D5F0E43,0x5E1060A794664062,0x1EB4F20C1087765C,0xBD695A2ACAEC28CF,0xA4C3CEB825DB7159,0xD25DD2953ED47F41,0x6BDD01E0CDB87F10,0x80CD23494774FF23,0xB4AACB21F63ACE79,0x2D06058E4F9A21E3,0x345D3B7F079C0214,0xE7C0C38D46CEEE02,0x330D4B3DC55C1A95,0x2ACD5EA0CA659088,0xF32826E1D45A9878,0xFFDCB8B0C9C42548,0x6C7BBD4E9A5EFE03,0x8BE4D932AD57143A,0x54805B0BD4158FC5,0xFDDB04D8C23E7D27,0x1EB910642765D7FE,0xA708176561B912A0,0xD1DACCA89D16B3F0,0x628C3E6DD1E6EFB3,0x21BAF164FBA0D9C2,0x87A18334DD7E669B,0xE3FB0B1D05A81D30,0x5305B0160DE009D2,0x7260936166977690,0xF40599512DEDEEC7,0xDD7828FC01777DE7,0xA665D1259E9C1D84,0x713CA00D1BF4AAA2,0xEDC4FB22BFD58473,0xC227DDB7D0F9BA35,0xCA3D7127A0EE1826,0x0FBD04C226C3211B,0xFB9034F2574D7688,0x6BEE33D264D656E4,0xFAEE478B4533124F,0x94B48ED70E1D9ED2,0x8CDEFB452820C318,0xDC6EDBC4AA4E9CF8,0x68CAE1F6F6CA6EDB,0x589C4BB27C479AE3,0x86B6D8A5EADB2F94,0x4F09A73CDF2CFB8C,0x25C4AC9F367C1296,0xCE2F0ABD08B421D8,0x38D939EC4F45E96A,0x0A5BC3C932B8CBDC,0x285D320EBAA126FB,0x74063EC58871B64A,0x6B9DA12BF1ABA454,0x3CFD9B3CA673D88B,0x441B1A10E7C06DEF,0x6BF3D370DF3876FF,0xB9D3138F9F23A75E,0xF6EF959122AFADB5,0x35D382DF005B275F,0xD04FE304C5B8DE20,0x8E8B97732A63358D,0x3C65AE42491A3942,0x4A7BDCFCEC3FBCC3,0x1F68BECF3B5E8A62,0x80DF1F22128C2442,0x5955EA5F31CB6B98,0x8F0E66394D5C09C0,0xFC388C0AF7044AF3,0x2869854DEF094B46,0xE4B0ABE95FA9B8B9,0x6169F4A02589A611,0x1BDE625907F63B67,0x77E044146C633F42,0x63DB357D5E7BF0AF,0x54F982E716A9AD61,0xC83F41E039B0939D,0xE732BD264591C485,0xB306C0840B890042,0xF0198532199AC05D,0xD6EED66B84066037,0x91FE87527A8D6796,0xE8625DB445DCFCDE,0x5E4855D6F2BFC0CA,0x97D36A1923C3ABD5,0x0F8434443A0A448F,0x8E22D02C0BCFE25A,0x70B972E7A10D9ACC,0x392CCDB656909AE0,0xE68D029538D8053F,0xEFCD5ECF4022C93C,0x2387C65225310606,0x3EFFF913BAAA19C3,0x3A4796A4B33AAD15,0xC6E0F14A23A0C71B,0x7CF1A0B7F6CC0D74,0x249EE7932EAA452F,0x6AD0FDA95D7EBEBC,0xDE36A49D43240642,0xCC566612D22D9472,0x97B204A50960FEC3,0x2C90951A5150D74F,0x0F23FEEA63A9139D,0x3CADAFFCE4B71770,0xBE373632E04881FA,0xE9E0421BA516EA2C,0xCF30D8F204A1B44C,0x0F835CA36FDA0B01,0x6DCF195C4B2DD918,0xBB7E3DB067A726C1,0x97C0F6F88F9D3F4E,0x1DDF4A82BFF634E3,0x856B377536BE4006,0xA66AE0D2D39AAEF5,0x06F3C3C5A416AE56,0x1830CEA8D45BAE32,0xBAEEF9F6478E572C,0x1B2EADBA0C7F761A,0x3616FAA4B117CE8A,0x5B6B70361BDD2264,0x1D09DA9035354752,0xBE22FE0B751F9438,0x7B8CC65FDBDB3E4E,0x04FAF63F364F4972,0x6B0D5EA4454B335C,0x0E7C89CAEAB4265D,0x4B89781D1EA5EF6E,0x5558A87CD3057174,0x87DB41CD7AE79FFC,0x333B45F4779BFAB2,0x165A7310880EAC03,0xED559E2DDA214DB2,0x287F26FAA354C3C9,0x1546DCE2291F4E65,0xDB272BF8C107201F,0x380DD6E729154A48,0xFB3EBE83667C6AE0,0x2CC02E101CA1A723,0x10776E5C7EDE5926,0xCC140DBB17B273A6,0x094F91FBEFB20C1E,0x519E87C2AF1E96B8,0xDE7E673809FC3D19,0x6775B00A20B5EC66,0xCC54DFD613FEBB17,0xB0C7E8BDA61A86DA,0x76B47015B7ABEFB8,0x51E1EC9A2C4BCCD9,0x3EA31BCC598D5409,0x175390D67DCC77BB,0xC93646E3D9DC1029,0x078E71442F7792BE,0x9AD5A2F8C97BDA89,0xE2EFDBF51591C935,0x7C8AF8871E43709A,0xBFCE8C73CF05DC44,0xB0FC609C9B0B332A,0x746FB0E54FA7B4EB,0x82171A8D23818142,0x427B1D51E142ED57,0xA1FC3CC4445A6682,0xEF91FEEDCAF7975C,0xC0A5D9E53C28EF80,0x49A526454C098369,0xAC4FECB53252EFD3,0x20A26B5683F768EA,0x087B81D77155024B,0xBFA10C55A2DB2BF0,0x8AE62AFF6C2AF5BB,0xFC8EDB0E90FAD159,0x5EADE669D977E9EB,0x477DAB8E51AF4E74,0x88556AA672468F34,0x6F9B0F756F1D1FD0,0x1F07C13A1E783152,0x9EE9AA3DA4FEE231,0xDD936A125A8847E3,0xE2194F5082A3BF37,0x8C4F5BF859786024,0x0DBD622A0B47F9E1,0x4D2F8E92CB4DB159,0xEA6B744D037FE8AE,0xF37F701D759A3B6F,0x677CCC6DB2D0E9A4,0xBC9492B8A01E7075,0x9B5BC8ED0741B1D7,0xB138669711167BF4,0x52B70D21BA66E879,0x13C721BB0E88F4DB,0xDF31A5757AA3A3CE,0x4622B5ADED8CFF47,0x9F0010E9B13CB6A9,0x5346BC72833BDD2E,0x41A7FFD4D43AF78A,0x00639F6BB02A7ECD,0x6E980279AC97E911,0x305339A85DD4179C,0x46EED9BC84CF76BA,0x474207E7CF5B8D50,0xC5A8B0D1BB6D41EA,0xFDFBA651A5985724,0x64ECFCDA8DCF91F9,0x2B1BDD092216DECA,0xDA12828480BE5503,0xB69E7986E5E7E6E0,0x4BF5913DAC6FA7D0,0xA695BA77F4660D52,0xBBBC73A46D838F02,0x258D75861ED46B61,0x56A441F47D227ED2,0x2370F5DE4CEF3A7D,0x4F9C512EB3FCF4E5,0x20258874F43C9355,0x570E69C0F1503E4B,0x3A8201C0D4C07692,0xBAA2E8FB571BD9CD,0x7818BAE3567DCACC,0x77B34B1D1FADA1F0,0x5E5CFBE4AE068B6F,0x6AEEB7322ED73454,0x08A63AE768BD890B,0x0A59E523106C68A2,0x442157DC2D802FF1,0x6AEA12E0F42B9068,0xE94E9F827AB695B8,0x27BA2CD7F2CDCF5A,0x3DE53A5077B05412,0x427FDD4C863944B7,0xAC89AF2836D2BCA9,0x6478C33014EFE00A,0x8FC73E3F41847303,0x2FA9CAAACFE18DA8,0xE00FD29AD723C4A6,0xDDF319DF3D96620D,0xEB95DD824E412933,0x0CFF4C996EAB34CF,0x49124F3AECBC4829,0x5FE2EDCB777E966A,0xE90E2C7BB1A31668,0xDD11D652AFF5983D,0x652C5F5D1AF77743,0x28D8D9610CF02E7D,0xA6344F65070A2528,0x7E4F97B60FE37D16,0x529D98EDC44E676E,0xC80746AA1850FCB5,0xD2B80E987123F42E,0x4A208AC7E32F0BF1,0x27A66131CB819605,0xD00B6E468E92D8C9,0x7A0CCFCE1F5E30BE,0x016C6A3AFF1EC01D,0x6D8DA5C00D8CE74C,0x0B5034E41624D158,0x1E8648C1FBFF07E4,0x31726F56C917B6FF,0x31A3B0F51CE5C452,0x0BBD03969198902E,0x7E3B360A5C251E26,0x097342D66A5F967C,0x912CBABF2C623A17,0xE65257924A88413E,0xDB37BFD8FADD091F,0x235E6DEE486E5135,0x78A82ACC4C3685CC,0x5AF1BB96E8A0E798,0xA50657EA3335DCDD,0x761DE44349BA6DF3,0x97A0772AC52A7EE9,0x67F8805CE610F96D,0x6D9B4859ECE0765B,0xC402B86A24418D00,0xE75CBBB78D247362,0x955405AFE2A4B2A2,0x507771518012B6B4,0x005210EB1BD86911,0xFC723BF50E326A35,0x31B3393AAC1466E9,0xEBAE36647133F02B,0x56B4803A674F9FE8,0x1E9C816F36C86C37,0xBADEEFCE6D0DA245,0xE84C202D6EF78D6F,0x2377E6200191435C,0x8EEEF822AA2637EE,0x35FE83543445BB34,0xEC8C431D80A3A932,0x0B25445EDB475506,0x5D47EE8D211E7667,0x44D28B80A0A92B26,0x6AF75838B0FF5A89,0x8DEDDA9BB8AFB9E4,0x66E27E364C3F46F8,0x56961FB0E997493A,0x197815EF4244B5C6,0xFE4C4F3D2855ED37,0x76DA44EE485ADD52,0x4881839A1B1C44DF,0x527E246D5DBED126,0x6748FFCBF7FA9D07,0xDD729FA5783C07E1,0x199356B9EC772113,0xDF6468FBC9508072,0xA45A599F2430532D,0xF8A585A164A3A08D,0xCD81A0FE5C33D647,0x17CFCC410968A4AA,0x768E683C9C0E103E,0x6BB090F3CAF7E0E6,0xA719FA402BA26169,0xF6093B34374CFE52,0x9763E4298F0A489D,0xB5060950DAED831E,0xD4B2DE02E8F6AE1D,0x4A6A9B38DEA8E02F,0x00ACE2966984BE37,0x59F78213CB460B86,0x0DEF755A415FAD42,0xAF4E2372859C7A51,0xAB8E5AD296760490,0x987CBD69344D5B2B,0xEC1EEC386297D530,0xFD80A8E06A2D6EE0,0x3F96D909B5FEE838,0x8DB9A1DEDB6D6232,0x30352C5EDE4BBCC1,0x2ED27141762CBC75,0xB44E45376AB80517,0x46A755B8B0AC1DA6,0x1BCA5E2ABF577D26,0x4FC71F800D2556FE,0xF29A4F96B5917F42,0xD927B2039F4B4FD4,0xE15CA26F1B3F603D,0x964AB8224D56C31A,0x3D2400CC930F61BF,0xB62B244C51B2DEB2,0x98672C9B33B31F8D,0x196266D8B24F2747,0x2DCBAD8051B1AEB4,0x27AF254745145680,0x66D9952FDC30B27E,0x7C30C63BDA4974E9,0x2D489FB1671FE09A,0x124E8A4296E2F903,0xF444B549136E026F,0x957DCF1CCAFC5645,0x110B600C925F31F2,0x01F936E22EB31FBF,0xE26BB5DF7D014643,0x53AC0D96991E538E,0xAC4349135A3FC7C4,0xB0CF0D181B4C9AB7,0x15AE5676B914CD2C,0x6F9132D09C90AA21,0x995122A2511EA3C9,0xD4C6107B925342E3,0xD85416654B658501,0x3B8E96BD15A55700,0x5C75C44F2D020466,0xF716AF9409F4E4FB,0xBBA00759316DCAFD,0x3CF711CCC43861F5,0x2BCDB61DE8DDD90E,0xB13DCCB2F4BF427E,0xE1286534EF6FFF75,0x81D3928370DD4663,0xB6D6C64A715E17DE,0x364E0FB664DC00B2,0x385E8283D01C09B6,0x4FB61B62EA8B7591,0xAD893A35824981A4,0x5F0D8ADEAACF5610,0xC2ACE603FDE2FD84,0x679ED097B426B7FC,0x82540204D1FB2EE7,0x312AFF1B40EEAD4B,0x64FD0A39E7F8E6A8,0x0F7FD0ACDCF85A7D,0xAF4542B90A693892,0x34DB4AC5D1A27B92,0xACD04923FB31CD3E,0x5C5F38F2B1067D58,0xD9A74FE650B8835F,0x1507CB66A0C550C8,0x4377DB461A8E8096,0x3DEBEF0D5AF7DB82,0xCCB0C2B3A8490DCF,0x9F79F2E35F5B780E,0x4E508FAA6ED9D265,0x3304A98F504AC4D9,0xA176D7DB8ADE11DF,0xADC903FB31668776,0x5F17BCCF5BADD8C6,0xD01A169C8753BECE,0x9B747746E9BDC10B,0x366A7330258C24C1,0x921DBF7E83704B34,0xB86C8D5E0FBE5500,0xDBE8C4A24D8363BD,0x68770DB68F7FA676,0x2C56A0DF05F3203E,0xAC8CB39A605B971D,0xC88DB2864A1C7BDB,0x02056046EC087385,0xB40E8D8577D13126,0xFF0B20F1A5884498,0x14F3E23227DC9FC9,0x1F3019A75392FFD1,0xBD42E9A82EF13437,0xB44BB1F31571EB56,0xD3062EF0EA58F653,0xAE72920BEE541D95,0x660035ECECD7E982,0x598FF66E25B2C00E,0xB37FD9FB0896AF22,0xC8E861947E07D834,0x3766DB104A10F1EB,0x00968CCCB318FB35,0xB443F749C142990F,0xE69AD923B2ECBEC6,0xF0A77973C826EF9F,0x7D53343EAFE4B0A0,0x3D6D02180E67E90C,0x01DC025E8DEBFA51,0xEEE2A45E45843B10,0x7A760F25D69831FC,0x30289D6733F26C85,0xA57E606CFD3B69D4,0x34A1BF95584C9EB5,0x6E3AB4A19DECD731,0x52BDB20B8D00E049,0xCB4DF8F79A576CCE,0xE865D942CD76A11B,0x8E8C1913490A8F4C,0x70E9358579D989AC,0xDF4FD1027DBEE5DF,0x2DF0BF5018EDFEDC,0x74BECA73047AEC81,0x0A6B52063A48B820,0xF101872FE2D5D331,0xD213A29733DDF767,0x1C4FDD525410E238,0x141B2AF33F050474,0x80C41E885ED3C4DB,0xBB3D72D042027E29,0x7FB54392582FCE36,0x016DC3C4ADA78619,0xD9DFF371E1D1C7D0,0x9C683DC0FCF286B5,0xDC7A1A43E664176D,0xBA47D8F589E6FF84,0xCAAEA2BB850CC41D,0x77CD5D4B9A761EB2,0x287094E3C0DACF52,0xDC68390CCADC1ED4,0x384CC11B9BC23B32,0x5F055EF02C6526CA,0x01A89FADC16D7A01,0x210E63A70DC03C77,0x99B0C7F963D6E1B3,0x434291E5C8AEDC89,0x76A65E8C7AB38115,0x1C81F2DE42D851AD,0x1A7C2EACE8F53D29,0x2C62291685930409,0xEB56EB305B8417D6,0xD709B1AEBEF7AC8C,0x56EEAF7FB2B740FB,0xA6672CE09EB4C619,0x6A959E3988957ACD,0x6828C77D737E2AF3,0x7C1A8B97A4F6D72F,0x25FB7376EBDBB5C7,0x12113ED9A3B6AD62,0x79EC801CE9CAEEA6,0x3C6DEFE02A47C385,0x9089B4CB0A56163B,0xFD247B75B522A362,0x47A106D6324EFCC4,0x6C5AA379D9FAA3D0,0x4879C2665CF19FFF,0xE5C108BF01D0F65D,0x9B8067FF87478463,0x86EE5FB73B8F2708,0xB9A9BFAE2F7672B3,0x71039B2AF99A626B,0x213E708BB2E6440B,0x6898F283C43E04E5,0xAF21942BA8140617,0xE1863C385D04A1EF,0xB204945804911171,0x81007A774574E099,0x4F4DCF43F0F87346,0x423B0EC29A5960FC,0xB8C9E3D6AF359BC9,0x7A01E26B3BBB8C01,0xB3F4E65F0F758FEE,0xDDC374D04A7AAA21,0x161E0BA00923DF4F,0x774EAE998CB6A9FE,0xC17248AA7B20F2C9,0x9AE8B6DAA29E80B4,0x5E687A6D95AED8FB,0xB0B38BD3B02CF0B5,0x2103B550ACE09806,0x96C644B7CFD9C707,0xFEE7CBDFF01F2A6D,0x618A4B02CD119A43,0xAE489518B831B0F2,0x34F9691741BC288B,0x9114CBBC8AC7C264,0x4EF3B2269D76EF96,0x92249DC9903381F0,0x77101FFF7573EFDA,0x2165285D680D2327,0xE0C82E0E2781AB14,0xA6BC9019B6275C66,0xBA8DFF2488185155,0xBD76E646A01D6C3A,0xE07F709827C8ECEA,0x5C9B0EC30C5D0D1F,0xA25413BBA05C6D34,0xD34B18002B8F35A3,0x571DE09343888034,0x65CACA672E40E6DB,0x05A33CB7053CDEBA,0x4BC441EE926A2278,0xFCF5F6D4A0734100,0xC3C476077EF9A5B0,0xA8C770219035ED8D,0xA82B97AC05F0FC50,0x98130C9F316FFCD7,0xF74A602BE572F508,0x9B699C9F80E25714,0x689680F7D9F987D3,0x96591FEA25A8BBCE,0xCF5D65350200C659,0x3DE1455DFEDBDA3B,0x8BC113E004E0D0EF,0x1994194701D0E7B1,0x3219D0DB6240527B,0xF0D9AA1BAB22CF31,0xF3EE5F264B127041,0x0DA6292C7E01D477,0x0A90236D0473B7BE,0x7877F5BB07068A87,0xF265E994FA0E9910,0x85BD7EC1A051D890,0x25EE021CFFA294AC,0xD1BF4C0AAB523C07,0x334BE3852FD013C3,0x9BBCA0E9EC0616EF,0x792CEF43219A2174,0x4238B7723856C389,0x14C7EC1ED60A20F3,0x01EB45BD41A19D32,0xC0A311738DF76AE1,0xDD4299E0592300FE,0x84F3DF99F0161C64,0xEC75CCC46288E207,0x0717D6C733DB24E1,0xC54AAD4CE69E37C8,0x9794E06D26913AF2,0xE566167EFFACC42E,0x9B9F27E7358E35D1,0x28B6FF887546EB76,0xB08BF829D6CE1DEC,0xBC5CA8DB08EDAA7F,0xA84D715A5E724530,0xB6196C6605AF3B62,0xD9578283C15AE3CC,0x8B181AF0EFB09452,0x1E42206E778ABB12,0x2EE744F71034DF86,0x8CE3E870C49A659F,0x246D5F39849A90AE,0xB9B248AE2C8C90A9,0xFC5470E4CFE0EF05,0x7EC563F8FD17764B,0x52D487B6B158787F,0xC058C3F7EE6369E8,0xDE18F7DAD895AB42,0x33258872C7236CB6,0x424FACE0D4032BB5,0x22F89FF7CFAD5C19,0x1F719D47F2D86861,0xFD9783186281D7E5,0xBE96EA3BE3480F55,0x64975BAF193D8B88,0xADD46759F485AEDD,0xA563515EBF353821,0x39E18C81DFC69F20,0xFB9C762867A58225,0x545A02E7085EDA1E,0x1368A61A5943B3C8,0x95E30FA76727535B,0xA6F6AA6EC9B8050E,0xE0D12391FB6D9171,0x435C91940F9BEB97,0x87A6309C73D77EAC,0xD367773B68D46896,0x962FB07B9D61A07C,0x4A18E80AE3E584DC,0x5E4DD6B7B1162B8E,0xBA4757A8D34CFD93,0x8348CA175D172B49,0xF7CB422D59525CA1,0xDDE1F38682C3F423,0x5A825FF25B6B405E,0x5DF4B797595C509E,0xFC61FCE4B549E012,0xEFC8FDDDC05EBB5F,0x3EA35B9CC69F3E1E,0x10BD6C88E01E6F35,0xC3DA336D0E665178,0x88B371D29D2B3837,0x0016CDA6ECDB9D76,0x998CE61994F9778D,0x8D9F83548DD94F6B,0xF42DA709A4BE7857,0x57F71ED7F17C0077,0xA73A0C67E2B710FA,0xFAA624FAE054114B,0x8B427E41C050BAD5,0x11AE1D786681455E,0x89093420FAC6113A,0x0D9C914996EA3784,0xAEC75FE79A0C13F2,0xA40008B78AFC536D,0x1ABCEDE59D65ED83,0xE4803F0BA60EB70B,0x7EF1610CAD9DC795,0x2C7318C2DDF99A20,0xC82AE55F77EB0ED6,0x52FC2244CF4BD47B,0x666B26F5E6F1E03B,0x368A9F92A05F90FC,0x7485FFE722BA5CA8,0x8B3F6FC1801F6FC1,0x8AF487A93E646EDE,0xBF5CD7D8AD531452,0xE45467BFA31DB730,0x7D6A090EEAC59C36,0xA162FAF65DC36470,0x1AAE85EF8F2C48E5,0x292B8FF22F488E5A,0x26BB39A856E71EC3,0x00BE057F40D9E6DE,0x9660FE50C012FDA4,0xBC57D04694C7D3DE,0x1765172E15883994,0x4F7390FA695ECA6E,0xFA4384A5268FC4BD,0xDE3D7B2438AACE48,0xE06D2A740B9FF21A,0x6B5C0F74DE9691B8,0xC29E0C78ADA693B6,0xB73245E20F8203B2,0xA6E2717224862343,0xE1A414066775EF79,0x807E4EC98E586E9B,0xD4CF6A48A786A74B,0x15712E5D70B55F5B,0xC4AF90D838939164,0xAA417C32407EC662,0xBB742B705AF04E12,0x3C8B537DD1B4A018,0xBDCD99D0359600FC,0x97E90442AB819EC6,0x3D4F175D1E859013,0x488BFBB4BED9DBAE,0xE5EC4CC9587E2F42,0x0714C9F5A89C15E5,0xA372E23B1CFE91C5,0x7A1389EBB0785672,0xFC148387ED7CCBEA,0xDF4B17B6EAB63280,0xA933C11CBAB46265,0x8CCAAAE91405AC89,0xDFA31B0BB33D2FCB,0xCEC091B02A708DD2,0xECD82E6CF02A1D54,0x7A3846D0A54F459A,0xF413415E7854016D,0xDC1F207ABD5273D1,0xB8AE89020EAD29F1,0x7CF318E9555F1D07,0x7E22AD8D6D53E820,0x41C8AF633135CB24,0xE2F5E5107036C3DF,0x61FE8B3EFB2FC80D,0x42C7EDF477E5B358,0xF4732DB65D43EC28,0x4FBDAD14DE7B4659,0xE3327B2680EE4D9D,0x244316BEECB0A081,0x24AC5DEAF3B86477,0x49E3A9A6DC9FEC44,0xBCD6CF4754A27B64,0xA5ACC149D3EF9F90,0x3DFC00688166A077,0xAF3AE37CBF672892,0xBDA7D8E0324D0798,0x7EA8F2D1B13AC07C,0x84F00029054D57AF,0x19766D1D9BB5CD0B,0x8B2C02B4C2C331AC,0x59C78BB1301E61C9,0x1FBBF6FB5F1CAA8C,0x4D83E6C5BD3176BD,0x85EBA9883799A5B6,0xCBC5AD5EF6023FE2,0x49426046D350C93F,0x5DF68017EF27D96D,0xC9D48794AD343523,0x0C25423963B434B5,0xEC7CD73A732E420D,0x2C5EAB52E9A8231A,0xBA2551056397C89C,0x058002ACE513375D,0xD1AF9083727FCC22,0x4C9C4296363E3C3C,0xD27F6CAAE5303345,0x3DCABB41EE873DD2,0x8BD9FA0AF21EA8BE,0x06BF0BF22C6E1BA6,0x75E527E250CF190D,0xC30EB2A9F0B243FF,0x9E767A54EA8473D3,0x5790925ED9C1C5A2,0x82B7EB1371708529,0xD68B0EABB96EDD83,0xC77560D949D22D22,0x8CD50D802DAA5ED8,0x296AA679B65B3CB0,0x54277F065845AE36,0xB60A3F61EE41E5EC,0xAC533E1091B7C386,0x5F471995EF72C357,0x813567BF962C1023,0x0C7B3B5DFC670E3C,0x0A3E1DBE01BDC39B,0x53004E7BDA179E4B,0x09663FBA1E2BA6EE,0xE835B4E8A6E24935,0xA8ABA962350E270B,0x583D5033DC21575E,0x2462F93A05F55156,0xACF0C4EA40EF847A,0x636A142296719FF9,0x608703A0E8D0F48A,0x0ECF329C9BAD277C,0x52DB7C435118A80B,0xEAC1D54B7783550B,0x94BB1E764A77EF17,0xB4797F2301D958BE,0x744BC13D94B67B53,0x4B249DA99CADEAFF,0x29330673C76BEEAA,0x93E21E574EE2C06F,0xDC59AE665AD9471A,0x97EFA1051F282640,0xD738798EB88DF473,0x5AB72F5F32AFE2E3,0x753EFEC8154C2CC4,0x053292EFF9842939,0x0A9816F003B55DD0,0xEC48E87A048B5B7B,0x6A4DD28762145F1E,0x5CCAFA7E1CFAE5E4,0x265B1E8A81FF1D08,0xE2603736CFB643F8,0xE5A76157639D0CBB,0x774FE79F6F91849D,0x4E29C3A99E313223,0x4C3B0AF6E1E4EDEF,0x54DCCF610EB5917A,0x07B0F67E59F3737D,0x77B6B34120B3EC17,0x8EB7BC0AD2FCCA13,0xBF9771B9628F2FBD,0x84B63C6F1C8B4E3A,0xC97BFBC378F1270C,0xB6E6F09A0047CA22,0x380D56B397F59C94,0x81B9E592B1D9F712,0xEE78BF1F8CC07C71,0xA07C5D02EC815C77,0x5A169BE7A48B9F79,0x6815973CAC55085A,0xAE0915A526472C0C,0xAD4FC9F0AFF3DB00,0x30CAD9DD783826FE,0x2628CA02997474AD,0x87904FC5F365066F,0x32286453E9092ADD,0x1702721E033FFB87,0xBFA04D2B9C80FB24,0x2D2ACCF64DAD3350,0xC2D1DF3F1A831BB6,0xEE34D07EBFFB3FF9,0x5F8825F0F50DEA05,0xC0B6D482E2D80E27,0xB2034EE3C57F62AC,0x5367EA85979AA9AD,0x3AADD9F171C1C33F,0x4487A4A1DB1880AF,0x06640A840ABE5DF9,0xE345E5D91BE65B24,0x90FD245F3953EF7A,0x1FCCF3E90D650225,0x1E6037FBC80F67D8,0x3C918BA852481E96,0xD0943E65FE1F563E,0x3523D0748DBF1F1D,0x11AFA5F9F8E43B73,0x568E74338E720B1E,0x3D04E9508F1F5455,0xF532FED74C7F6DE4,0x22A316FDEE84855A,0xE57173A63B62EB93,0x44B0E782F71F86A5,0x8CC8248AB0EDE65D,0x709C02E52AF669DA,0xAE5DBBECA68680CA,0x9B504DC6996E7C7A,0x6E9557DE3FDC1306,0xFEC0ABF612972A1A,0xEBCA6E732678AB7F,0x98CA3BCE693ED230,0xC205F292CB72E2A7,0x4FEFBE92229FB4E2,0x4AFAE0A23EDF8E42,0x181903FF18B3F5F2,0xE6130ECF273C2E8A,0xDEB211FFFF0764F9,0xBB16C04595193696,0x2B52BB2240543E00,0xA22690CF689C982B,0xD770ADE4724388A1,0x5DC7EED004376240,0x4CAF7AEFC1BA5F59,0xA6AC433429DB80D8,0xB3F59623BA742407,0xCB8681A55F361543,0xA8696B629503399A,0x1F0839B41C9870E7,0x75E3652660CDDC58,0xE918077B2F2B7BD6,0x88B881AB56841289,0x871A33E3C579DFAF,0x4D91325D7F152634,0x0963B98D5CEC6E82,0xFF127C865CB18A96,0xA55C001A6E5DE722,0xC809074627732C1A,0x8C4D3552D0390B68,0x9EB3BFCE38A9352A,0x9449B7B05A65D657,0xC7DB28772E22BA30,0xECBBCE65899CCE50,0xD70B73DC2AC7591D,0xC615E92C95529A60,0xC588E099D0723E6E,0x808CFA5D6F6CA273,0x40DDF66D3D7D8B3E,0x6937F79B516E7A4F,0xD95976DBC1C6DB7B,0x1A598C3A727210EC,0xBB9A6ADD079BBCA9,0xAEC02884A3C932A8,0x0C4C548BA900662D,0xF7AD4ACB9A6E99A6,0x89F916341AB03515,0x5DC9EC8C0B9624C3,0xCF3F57A310EA3721,0xE98081569F00BE9E,0x43FF1450DF8CBE0C,0x6E1D31AB9ACC6D00,0x6863A97305706C23,0x8A21927C86E4B42E,0x23D1FA623B6307D1,0xFA0DDB8489765574,0x04FD43D4031A4E73,0x2C86D71A346F3485,0x054BC75E5C7BE8C5,0x3BF05903D4180DB1,0x210AD7D241AF3373,0xA4E6CCE1F8161540,0x902CE21A86680CC5,0x973AD16D950A74C7,0x5D4FF097DA743E0A,0xA03AE1271AA8D218,0x2C47FAC2775A5852,0xBCBA5C6D2C272736,0xA7C3DB0081A74A2D,0x6AA55630922169F0,0x618A7F48541329D9,0xAD516244EC35AA6C,0x8C5999CEAE55262C,0x7DA9C725F9C5B476,0x16FA2D831FC774DF,0xCA96BAB869EFCF37,0x4E4A0CDCF995474F,0x1EBB69E47F75A725,0xC18BD312BBC34AC2,0xF04FF29F4D3D127E,0x0C68F59725B4BBDC,0x5BE77824A97250BC,0x507784030F4A8322,0x32B02B38588CD7EF,0x347646489569A66D,0xFD37BF7ACA575175,0xD132B46301B154A6,0xB0F6385D18A5E71C,0x3853510B50DA13E7,0xFBC1B26E2A42ABF5,0xCFD55C248593ED2D,0xF2A42347352CFC7D,0x125CBF780A46D39F,0xF663B70C4F7DA6D7,0x90451AB736CDDB17,0x75B2E82FB77AD62D,0xA3BBE12111C11116,0xFB4018FBCC13B422,0xF3AA8508B41C0D96,0xDE992EC41CAB551E,0x1ED9B69E0415A5A9,0xE5EDC970949761F6,0xD8C97583E99FE1BA,0x85B47F47D854C033,0xD70973564611C9A9,0x7A9EF4EFE6F5CC6A,0x4F0AFDE2E7B6A26B,0xCE5551446ABCD8C5,0xBF20E2991276AB8D,0x9AF24C7A4C30CAB2,0x5D996AAA6364BAC4,0x4C42DBD317D724C8,0xE759EE1821095340,0x90EFD416984D373C,0x14CF0480D989CA54,0xE293B6634D3899FE,0x8CC0A5DEC2A0003E,0x121427550538C140,0xD235D625D0777312,0xE074AFC3B04AF4BB,0xA42D61462ABCA85E,0x68433F3407D0BBD1,0x0DCE5B2440445C87,0x4D9F2C4FA508B2EF,0xBA8CB644C6963102,0x52502D0D8D3A7BE5,0x1C69BC7516EA0DAE,0xA2DCFF1EB925E81C,0x87E801C65AFC6430,0x0215F736B64A02C1,0x038CAD3C40C66BCB,0x17D31A505C76A602,0x6278F951C512948D,0xC5708CE4384B1D85,0x55214B1C3BC125F9,0xF37DE7F18D200EBA,0x7C267204C52A52F6,0x0DA6906F68638CFF,0x813906890315138D,0x99003C750D85BD78,0x249FCC4C4CB1F61E,0x4FC479F50FEC787E,0x22B35E16D1AB011F,0x76E5DCEC2F5595CE,0x94873DCE35F915DA,0xEB38CA3612EF3990,0x3CAEB5618173C146,0xC2A96BC6B106DBA3,0xD60906C367FEA25C,0x440F8B1E11AC1194,0x571DD92C94550F44,0x40EF974DBD84E8BE,0x40B143033B1E40A1,0x55F41FAC72D5AA6E,0xE9B7BB5CEF6692B4,0x989127E5FD9C1FF7,0x32A03414D584EDAB,0x1B45D1D4F21CA1E6,0x77228C746D686242,0x41CA5AEA301C302E,0x2AC1A14CBD360706,0x0A22FF984B15E60B,0x5C416B686BEC0597,0xFC089F12A3211186,0x707175EE0978D1C3,0x32D2EE28045E498A,0x3A2544C1F0AC22CE,0x3947E1CCC1C7D1C3,0xA29559B6F1D06EBE,0x2013E2BFA2903252,0xF8A002F87BF26668,0xB13094DEBFBF4DE8,0x3E8A0F9C2A68F459,0xC8641A28F67BA52A,0x08163887C3090EA2,0x09DC826243EC2AA0,0x4A61724178398D15,0xFA419E3E06749245,0xC9E7106564F5EE67,0x14367F487CD19328,0xB1168ABD559AFD53,0x71820FBDAE1931AD,0x241C361F326A2D9A,0x07820ED6AB815E4A,0x4443082333288E06,0x2BB060304E198A8F,0xD6F364348EF86718,0x763783E55324F733,0x3B18B934526C49AE,0x4DF7F78ED98648CB,0xC750DB13C1FE9B98,0x68A571C529CF579F,0xDF8A23133D1E0E8D,0xB4E27F8AD9BBC23D,0xD7A5F4F66AA6DED8,0xE710EDA307633340,0x967FCF7CD2DA6B96,0xD23810EE32183633,0x00AE4D397360BB14,0x5BFE68AB8CFCCA76,0x57136815266D3F7C,0x52FB4EA38320B638,0xDD1E70EECF8911BE,0x57E49F26C1EF56E8,0xB45B891194D723F2,0x5AB4C0CB74690BDE,0x20B6DA8F3E93188A,0xF62EBC197E411D6C,0xB427FC9F4F793149,0x1D6DDCBB6E83E285,0xDC77CC09CA9016B4,0x419B69469EBFB0F1,0x39141A4D704313F9,0x5756C5D35D5D3DFB,0x639DD75A44370692,0xC2C9EE9EE385F9B8,0x3B58C4D42EE12724,0x9E5C8E7C4402F283,0x2BBE244A08DD3D15,0x5F6E80A28E0DEFA4,0xB8B033EA1EFF027F,0x8169C5434636B75B,0x0AE49C413E3B0F58,0x331852FE662679BF,0x9C70329FE3D979B0,0xD502E68215061536,0x91D621A9A0A45B8E,0xA9595D26DAE80461,0x4322491C9A92D3FB,0xD10D9F3E268AF19B,0x5DDA3739446CB5E0,0xAAE721363E6A0468,0xA81525DA1EF8821A,0xEAF456D9601757C5,0xDDF867E361A32F18,0xCD6AE19694A967E6,0x23765C2DF4DFFB14,0xCA1BAD6625F83AA9,0x5F4FB4A4239032FA,0xC91434482DA9511C,0xBF3BD68B2FF61B22,0x3C7EC044CF32880B,0xC2A8AADAAC0C3851,0xCEE89B52895F7168,0x7B3F50B24D4C592A,0x17B8BBB914E615E3,0x73C8DE95BAD28405,0x6DE00600D8A96C76,0xC3ECEF6921ECD377,0x33799981B0738622,0x122901B80BCAC8E2,0x8BD73D37D0E6BB9D,0xDA8C9493D9D2A3CD,0x12F8F63A63082DB7,0x131A7E58A2F9BE7B,0xC8DCA7FADC3F3827,0x773D2A5A68B5CB81,0xADADB3163851610B,0xA99C15115A348A72,0x2C34A2F81B160078,0x6819C9AD51D216DC,0xD7A850FC65648323,0xBB1282CF3B33E82D,0x092CC3359549E6A8,0x98BFAF3AE63DBB70,0x6DAD3A823B2065DC,0xED812548E54ED278,0x4A4066ADAFDB6544,0x0B9210DA3A125E53,0xDD2842E482FCDB94,0xFC259EA012F2D833,0x3943A6CD72842EE1,0x1DCCE00F42317711,0xA7CDAAEB1326D88D,0xCFBBECEB8FCBE714,0xF0B143B5ABF3BDAE,0xF6E7FC96C14B68B3,0x8F29B35D4F70CD14,0x9272767E04FB11C6,0x6E5E1E975A70065A,0x8B868587434A6600,0x1E8F088835304224,0xE6CE3C9B99E53D80,0x5406F0051B7CCDD9,0xA69845F9BC81E678,0xA122DCF94D810A44,0x26DD29954BCDA5E8,0x6488E51034EEC73C,0xC72B6E2AE9797D01,0xB177137C82FF9035,0x4C7BE22236EE4AF0,0x38AA7F0D2ADC86AC,0x7B62F055A5D8CFBD,0xC4F3B1403F3E5536,0x74BA1F1812D0B287,0x493CE90FE778A597,0x735BFE71CAF9B3F8,0x7BC8B9472F15346A,0xCD7918513DDDA383,0x48766259BEA20693,0xF70072629BED3E21,0xC90BC858B758DABD,0x4B192AEB15FDEE2A,0xC5B8836AD85574BA,0x769E35ABBEA99AC6,0x9B1B65850CCB9399,0x7667E472C03D5ECE,0xAD80162CD597E671,0xD2527B0814F4C5B6,0x5B7EB678944FF6EB,0x6422539E76B95E36,0xAAF8D769721B7E0A,0x2FFBAE3E19F23AB0,0x1894847A5FFB59DF,0xC405E78255834C80,0x963AF29B50544A8C,0x2AF82A184E07B436,0x2209F2DEF971FF95,0xCB07D0F07A52DA9B,0x17557E9BDCEBF174,0x0F81692D086A692E,0x91C65A37AF680A76,0xD9287CC7E019448C,0xE393E9C3389D3412,0x953CA819ACB1CB49,0x23E5CB54D498990B,0xF708BEE2EBC97171,0xFA9775032FB17820,0xCC9A224CC72C6861,0xCADAE7BB1F8C3D96,0x08CDA3A556026B05,0x423B75DEA72BF0B6,0x3E2EF85F14E4F2B3,0x5A651889B9AD7C8B,0x4D4637CA88A52D24,0x22D29FD56CFA401B,0xCAC7A46CF02AEE0E,0x4AF4EC9B06D7CAD8,0xBDF94B0BE78EEC0E,0xB50CE90DA2292ADA,0xED344433A3CC19B8,0xFDC2C2EDFD6E945A,0x10B0B8797C73E5B9,0x4EE8263C171097B6,0x12433CBA8D3EB293,0xCB5703EE8C3E2B59,0x73416084454D8D1E,0x62EE8F51C5952D50,0x437B5ADA11042C55,0x4A9EF403280B7B6B,0x5527F2BBBC6CD3AB,0xEFB166FEBD884CE0,0x6225C897E16D22FF,0xE78E1987F9D8638D,0xB18BA25AD201540B,0xD17F7BC895958584,0x9CAE391C85FB5338,0x4C94CFBC3B996B18,0xF30A82A3514CE98A,0x0822F8E716736AC2,0xABFF8102688411DB,0x485620191414CD79,0xA47A5E5E4393A29D,0xB52F7559EA9CFF6A,0x5DD553B3476F8BB2,0x9301085DE84F87E3,0x6558861B651D8C7F,0xEACA7EF0741DCF6D,0x3AD49BA60EA86815,0x0BD57C1A19604C14,0xD46A64BC8881AF19,0x8131EDE0F88E6BC5,0x25B8D0B1912073B4,0x96B70E5EE4E1A109,0x8920DC13E4839C1A,0x5046CE1DED618F9D,0xD16AEB253AC977E1,0x53D452E9C5222509,0x92D23F28592AB400,0xA45768C888C89E90,0x3DC4BFD70D39430D,0x75CC2CE0E662B350,0x6EC87F9EFBD674DC,0x49135C99A5301EF0,0xB2FE65AD1AD2B535,0xF40EE2C3AD7C75E2,0x1E5EC2736D3646F1,0x2758BEFE02896CF9,0x3E0F2A2BFC9DBD40,0xC8571F4445DA8199,0x6D5CF296B33DFEFF,0xECBD673B887DADD9,0x0C6D3D23C514FB30,0x926EEB4EE1D18F78,0x1022859832308DE9,0xB0EFAE56238D859A,0x67D247034E13B7BA,0x2FC23447A85492E1,0x37DAB90D10E198C6,0x45553CD055B6FB2A,0x63FFA4376C946280,0x0B8D345C1E227791,0x8525A69D68BE514B,0x6DBDC769841D0290,0x30B8113421916BB9,0x1B88F3D919C295F4,0xD15D04DF38DD3270,0xB49EAC192CD855AB,0x4C87D4AD5BA17C8B,0x2115E508FBAC9450,0x7BAA6D34F3AA9F2E,0xF0F4DB6368536972,0xAB6C215DAA115072,0xEA45F5E03C62E747,0x110B69FB38524665,0x0CBEE77A1402C5AA,0x76EA89B31514BADA,0x1C9CED2A2A0CFA71,0xB15678535A1A1824,0x46CB2909F96C8B53,0x3C9FFD66C96290F7,0x1FB6B574A5BFBBB1,0xB1C7532D482BF861,0xCC9925FE9BA143B6,0xC13CD9EBA79CE549,0xB96D057D81F5695F,0x52CFBBB50DEE6881,0x54AB7C83D1CC0209,0xBDB02F1C8EAD6DE2,0x5913A673ECD0B47C,0xEC76BDBB4844A02D,0xAD42BB96025E2EF1,0x644F7DBBE4F9F455,0xA9E080F7239B48DB,0x21390B64D256BB34,0x5E1D1268B3B4003A,0xFA07C56D9DB25CD8,0xF5540FB40A101106,0x8AF459E2A4F26804,0x4C9AC92A356A4621,0xB7C3D2E8176E1EB7,0xD61C1D958FB0AB4F,0x867FF7B0489BDCBC,0x7E7B1FC1A3CE4B18,0x1A3AB0EF19FFE24F,0x1B2835ED8745D972,0xE01B55819116135B,0x5D436E8A0BAE26EE,0x9C6FD0D804B66596,0x150A900D8471CB10,0xCAD7EFE606847870,0x5C74C9A8A93767B1,0x0542823F4118D06B,0x26EEA1C964915CB5,0x366433DACB519F91,0x87D44D9A114B3A83,0x0CFA0EABD225A461,0x3D5914959162E602,0x4CC4C49500516914,0x6EF97E134C951A59,0x40F08AB0B9DEE662,0x8D3A406B105E7023,0xDADF3E2C8590D79D,0xFCDE701B470B4ED8,0x28EFFAB40923D30C,0x58A6C8A4111A303C,0xD5CEB6E62A0BA969,0x0741E44291B55F14,0xEA6692497523D949,0xA420B5CCE0FD73E9,0x97A50F02D5CF9F36,0xF65D9CB6EFB29F43,0xE17B7A2B7B61E20C,0x91E67FA66C385D2A,0xD608C36091BB5348,0x335641D2FCB0DAA9,0x88EF43AAA83E8A84,0xB00E2D8D16F78E30,0xD4B1436CD289D77F,0xD8855C3883AD96B5,0x0605E639738D3864,0x28891176774DC7C1,0x2DAA18D135119EB4,0x469BA81283D65F11,0x21C3C82219D1E6E2,0x1663112D7858A56A,0x179B3F5DA6967D42,0x7BF60A3BE3B88950,0xC22BF6E8DC511052,0xD78E01324223D1CD,0x9B176178FF34D90F,0x451E97ED01D6367A,0x081FDDBB9D99FB86,0xFF06C9795779C646,0xDB9F7CB78914E8C6,0x20FC2E539FC42F63,0x6AE04E384D112B0F,0x9F7CFD1941E1AB35,0x508BDEEBE00EBF45,0xBCCE55525EE2152C,0x0F44A4D812C23F74,0xFB88969E01CD2BD6,0x10777F41E44D7539,0x89179B3DE11D8CFB,0x81BE8ABFC59193AB,0x1AB5E598ED86F7DD,0xE1004996423012B9,0x75B0AECCADA94C35,0x78419BB2797DE7A8,0xD7D385F19C0CE315,0x29F162D5EBF99293,0xB427D72625280153,0x03A8264A36E6F407,0x4E741DF3CC38B72A,0x2DE1B874A0D78F70,0xE7EEB657810C4A73,0xAD7EE404CE472986,0xF077FC78FE5B0812,0xAF29F58538246947,0xB6DC4811461A9D10,0x6CD42A86E90D84E5,0x2353FBE278FD91D2,0x3EC8C1792B6AC370,0x54F9A5223E42127C,0x8C634A5085D8A723,0x2D52099F883BC0B6,0x8FD35B8E5073D6F7,0x6F1BA7FF04A05840,0x540B0C7282DB812F,0x910C26D9C85DDAE6,0x4A1C40754A5E6D82,0xC3A08AD735965C79,0x6A52A06EEF91C65D,0xF884AA12FFDC5E22,0xA02B4F35F961B589,0x801801CBFB44C2A0,0x0EE7DC32ED313E9F,0xD0C75020ABA757CB,0x3339AB05B29E3027,0x0B19A0433F3340C7,0x119E52974C50417F,0xDD9124BE94FADBB4,0x98AF485BF8ABB30C,0x2CE59AB062030206,0x1B5653D873176953,0x26E264B488B290CB,0xA592AE38E20984EA,0x5B3B09FBA3DCA87E,0x5267016CBEDEC608,0x40CC1F3D2818AEF9,0xE4907FD818BB03B6,0xC95DEBF912EED8B0,0xA71555E2CA2B8414,0xBBC746E215888BD9,0x5812DD713D742770,0x69A3F2FA3DFFB3BE,0x685CDF3B723936C9,0x9B7C431A57B440BA,0x33FD84152974309F,0x44315470DF93D81A,0x70D53625AC62B5DA,0x131B0437D371D388,0x1322777CF4370E91,0x46F170CEDD455350,0xBE6C83F6397B4166,0x0C16AABA0AFCA98A,0x8B968CCA5C32E8EB,0x91DA65C584C962CE,0x13E50DCC2C42E472,0x0300C043E252E73C,0x53F2EA283F255D59,0x50A91A64B888E17B,0x8984B6A0222A7AAE,0x4B5CED66AC2B853F,0x3242B63C8CC43D48,0x8E6385523BCE48CC,0x6782AD04A70CC24E,0x4D1450235BD43497,0x32B7179B117A4B25,0xB3A4F0F36A60A84A,0xE7AC274E1D3B5787,0xF854BAC1411751F5,0xB33D50F74A656860,0x578703F8CEA63D6E,0xCBB42C19E6926FDC,0xE5FF94EC8EAB556B,0xBDC447F5222B3AC6,0x6CEFEAC18DB5CF30,0x3A6D24B789049070,0x7BA1A164D8E30E93,0x4B19C1B82E4EFE97,0x43170D349CB2C356,0x48AA5D0325AEFE1D,0xFF287C8668710F78,0xD80C443934982CC0,0x95838F0D13FBF685,0x4A666A14D152ABB5,0x0ADF7946EC4310DA,0xD6624E03B079E025,0x8254AB9F17E94B8A,0xAF5F1BD4336D5698,0x4B9F43929C2E7996,0x6F61BF38E70CBA5C,0x0C4E62ADF6E0CEFA,0xC68B659AD25B173C,0x1AA846E59959C391,0xDD517406B7C1DF01,0x619C1263F390D48E,0xB9A2928EFC14CCF8,0xB980079B92997266,0x06548A9338CF0418,0xC6DD814E99BEE6C1,0xC4F491A7F4AE33F9,0x84861ACDAF393C5C,0xC3C443C09901BD74,0xB93A3C07C2A2B81C,0x021D58790627DE37,0x203248CA2063BE2A,0xC91F44780ECFB541,0xEB87CA3433A42F75,0x49D6E51EEBA8690E,0xBBD8F2CB0B43B685,0x33CD3C849CBFE331,0x8C634B26831B2EBE,0xB987F66914704E09,0xE2BC6944A0196B6B,0x2794B21639CC1D7A,0x01079A697D10BD8E,0x325CB17B228C2D2A,0x416411ACF8122A35,0x6E19F91E225A917B,0x7D3718C435CE5360,0xEC9D1DE9E5860106,0x677946813737AB80,0xA9FCF88EB32A62A5,0x26D56AD4486DCE8D,0x71E1E4F298BC49FF,0x5CCCE82786F767C7,0xF884CC3A995B4E0C,0xCB4DF6C435AAF053,0x8A5D9F9E5712CF00,0xCD0ED801B66629C8,0x90FD5AF61033E924,0x44D4CF2A78800784,0xF94B552B2F6A7A52,0x73F0BD015F531947,0xFB890F9D1FA695FC,0x9C4F96AC345EC675,0x61419EDAB5894D85,0x8681D159BD36DDE0,0x8DFC290971E6F3D5,0xC3373407C1FB0E34,0xB29C386A72D55852,0xC3F4472053A2492A,0xFB9A33CDB11F5621,0x6E7A82703CCC8F2C,0xA6A27DC8031A0547,0x0C8E42EB35282B0C,0x6BC1BACDACD5F5E8,0x8B54B5042AF351F4,0xFB334D3BAEBFDC5B,0x7EA0D524B5F4E409,0x72A759C2C0215ACA,0x1C965DE6DFD3EBB0,0x9713625ACC3EF84F,0x8A399E65E726835B,0x802952212AFFCB26,0x2D259825895C990F,0xA17B7238654013C2,0xAA84B8F804901FFC,0xD90280A43C8BF2FA,0x93B3E859A414AEB0,0xE64AD675570D21F7,0xECB27F91C4C9CC7F,0xA92D4388BD15926D,0x7ADE4281C4D2C0D0,0xB6B8D2ED8F53DA5D,0x3393F0D819ACB4A3,0x10E4D3F13F0A880A,0x3B86365E7F00FB60,0xBC719A2063350856,0x165FCE9A7C91F615,0x34E934F47D8C52F1,0xA90DB72677E5611E,0x55D52C06F7E9354B,0xD6056932DB1A591D,0x481EDA3EBBD37623,0x69561ECBFA9594C2,0x6E75E0AF1FADF19B,0x84088DB21E83CC0B,0x39BDBAA47502C9A1,0xCBFCB5DAE0DAC95A,0x134BFC66305CB964,0x8760CCA132E3ED08,0x6DBEF4983293A707,0x41F1C5401E886A43,0x47FACC91616DAF10,0xF7E4C4F5F00F300C,0x0878CC2E7FFEFD47,0xE0A8D473E75DF3B4,0xB9394F9224A9CB24,0x182D33FA675D9E6E,0xA77B8BCBFD47B82A,0xC4F9C7C24746388C,0xEA7F4D46DE9A141D,0x292C27E00ED21077,0xFDF23AA9E7F298BA,0x4B021D0C64E46842,0xA0FD5E41CEF441C4,0x7E763218AE5011DC,0x3E2426E075C1D3C0,0x66AD63A32A2BC145,0xC513D01DB03CF16B,0x85563057E8424AD5,0x85567278D939FE32,0x1A4F41E24AB25043,0x0DDF29F6285EDCA5,0xF5655BBFBF8D738B,0xD6346C05BE7992EC,0x065469C9FE5AF55E,0x7D4D8162A4333334,0x8CFB95CE58A86DE6,0x73E99772FB0F8305,0x0F820BFE87DCC7BE,0xA8BF0AEFA5B12C39,0x91A2CC2D1BC0060B,0x781D5AEA3381669A,0x76BEB3D8849CB7DE,0x1B2F6ACDFAD46536,0xEF5A10C61E997F27,0xB1456839F53382A7,0xCA9AA4883B1F37A2,0xD11B37E4E277A0F8,0x641C645C043400F8,0xC40AAF8CB19381A9,0x193C3ED788144355,0x08A81A69EA4FB4DC,0xB9A8E36C5BEB8F5B,0x9C88F828B0748D65,0x68E80C0DF0D1A035,0xD9FFA2F20D86E8A8,0x086F3D40EB1726FE,0x2E27FDE99712470A,0x09527981EA0EFCBE,0xCD1240F5C4C48359,0xE92CB7FC995970D8,0x7D7F4EAB5B5CD3E2,0xE1CEA9EB83066118,0xAB3082C4C91175FD,0x78612D9BE4516326,0xE9CB37849BDC0174,0x00C30C4DBEF1B56B,0x37861A15C9523C0E,0xD4C88A9835899941,0xBF6F7336277AF710,0x824D7C7675BCAC88,0x2B8DC4B477FFBA54,0xAEE68E9469B6DC2D,0xF3A72FEA5AB529C8,0x3A4AE0D929443C83,0xF973DF4AED3C0946,0xFEFEC55D991A6426,0xA8BBC6C91A988B4D,0x71582555DEF85CFB,0xB5D689C23F3CC2EF,0xE4BA7AC9946CA711,0xA6241E14F2D0D2B4,0x72CBA4BA10F6A407,0xB3CB74645AA4DB18,0x101E986FF2A78920,0x75560A392742E36C,0x21BFBE6705059684,0xD115F335AF611B5A,0xBBB97F4037B3C4CB,0x01AA4DA1FFBED064,0x6825A3DF7409C90F,0x097757363CDBD4FD,0xD4FD8A5A6F40C385,0x163DEB302FF6BF95,0x177247239D376059,0xE43FD0B76CF2945B,0x819602943CEC0454,0x5D6DB7D8B39C9C71,0x0F6215799E691E0E,0x3FEBF3678D3FA131,0xB62090651C611567,0xE81043955A741D9D,0x5BAEAE6E703C5B69,0x85B6DB28EBF3E9BC,0xAB4AB5DEF3003B5D,0x47AB3B4666727D9C,0x0A400BBD230C5F1F,0xBBDF87D5528E1AC9,0x87F55C3BA315E17F,0x9D40233EF93152E4,0x9EB14446B5D04FE2,0x5BF16240B0E86181,0xA5CE3A358AB2A803,0x2E17065D1D8BF746,0x77129C5618C79425,0x6985C4DB327BDCE7,0xC40B35614A7E200E,0xDE37EA5253CD47C2,0x38D218C04E836406,0x2343F8CCFB0F94D6,0x02EAEA02CEB82583,0x60B7F9388E478D91,0x18C7854B5C1560AF,0xD08D102C9F6A71D7,0x5F0394744FE8A6E6,0x71AA629556ECADAC,0x67385FBD2D8BA4CE,0x35F4D7EB53731AD4,0xC6EFD2458D716B2D,0x2D45D1F36643DC4B,0xD2208B05285D97A3,0x741958981E2E7CD0,0x3B20F938A010BF59,0x3953DDE9EEF85B1E,0x139A6B1FBA58244C,0xF96133A6BE25E2AA,0x231465AC93E44614,0x0AD54A102FC34AD0,0xA15184ACA632E1BE,0x6A6BA59BA7ADC7C9,0x655AA8A35EB69976,0x843249AEF1DFB9FE,0x98FD8B1F8843BDA6,0x88ECD0896A76F4BC,0x2F34EDB7BC660BE3,0x6353CF3A7E960002,0x5B076879E8FB35CA,0x9F649113D41B01D7,0x3A3F03A6F40275E7,0x74ED0C91B9338C4C,0x2E00FAA589A8F497,0x3FF5FE3CCCB3A404,0x0D585E307E17D57C,0x73BAF862BBDCCFF1,0x4F46DC5D9EA03F98,0xD9B7AE296E5BA6D9,0x5B3D34C939B5EEFB,0x299F3995A9ED9B90,0xFE997F3757CD8ABE,0xB5131D728B4AEEA4,0x29B1E1CFB1DF9834,0xD382F7AE14905053,0x5B0EDEDA41E529A4,0x0E335DFAB46EDA49,0x69A3CB6C31F6277D,0x56898308F87C389B,0x3422AF23B9D69EA4,0xCB111810DA98728E,0xF713660C904B1828,0x259B74DBA02CAF74,0x3DEABFE0513C5A52,0x016680F402DEE030,0xDC530C712DA63001,0x1CC6052F4C520095,0x71E1EB6084245F46,0xF0DFDD4F11AF7BA4,0xBA2B0733C7111EA6,0x10FC86A74D4DF554,0xBD8855197124C5F3,0x337D823D64D99FA8,0xEB1F984CE18632EB,0x0BD98EB38EDC3B56,0xD3D54C2765DF8ADB,0x7E2416199369B123,0x10B6DFE94CF36D44,0x3F85CDFD18B7E560,0x361E5950D6D49B9F,0x0A28E810098488D3,0x5851C4A901E6F465,0xBC2B48B07DEEB4BB,0xA52ED36C35A8F512,0xB000AFE43A4DA98F,0xF5EC3D1A98964F42,0xEEB92D6C5A47794A,0xD5CD0882AFD178E7,0x06C2182F23CB19E7,0x7DF7EEAA98AAF0E6,0x60F4F9A4F1A7DDA6,0x3C014676F55A0C21,0x8DEE417946F32DA4,0x9A12E0CD10D30D44,0x387ABC6AF238AB14,0xCF274D6945FD7CF4,0x3D51EA820D509410,0x3CDB03864FD0061C,0xC9F2192AB5BF7497,0xA673FA38DAA342F1,0xA39D560999E4F6A9,0xDD07142AA386700C,0x0DD3C4283C3A6859,0xC667E00D39D68ECD,0x9BE9AA5FCADC3786,0x76BC01D098795485,0x0B695F819F962DF9,0xAD1D7E34A68813C5,0xDDC2B1766F9D6A51,0x9D4883CA134FEE1A,0x11515C06D61856BC,0xDBC58E1EDB63124A,0x5753D7C63F0754A2,0x3DC86719346453D3,0xE0A56DEBEE810C23,0x2850C7264B140F79,0x2A87101D220EA76E,0x83521DEC54070698,0xE00A1D2406041164,0x1164642C10950CB2,0x8077365721F7153D,0xDE6D064DDDDBAC98,0x3DE68D1850C6F6EE,0x2A5011A4B1C205A6,0xA5816B5570972902,0x40E11DDF45E27DDA,0xEA0E1403558BC77C,0x56406920158CC085,0x6183A702BBBF4321,0xBCA591B8E52815D4,0x515FFCCC3AA02A6D,0xDE51739338745D74,0x1772B9356B5A671E,0x2E37BE6F188FA1FA,0x666E34DE13885F10,0x3282828974297B8B,0x065026504FCA71E1,0x25B89451E61D248D,0xCA2CA6CAF24FF9D0,0x9A8A00A20CE9CB4D,0x2E005120629E070A,0x23FA6B85E971DE1B,0x387C6442C9271573,0x1BA1D5E165A1F516,0x1BF6FA1282114148,0xF581DB130A35FFC7,0x332D76972D58517B,0x219F5C2D5666E049,0x3CB7DA5B4AD35FC7,0xA1BE344379DA84C4,0xAFE77CD2120E9D8B,0xC55D8311397B1982,0x338AB5E53CC5AAC7,0x8B3D4BCA6996E27F,0xC05E07F953C74B25,0x37AE07493C99AD5D,0x9257A27EE458DCFB,0x83A2043349B55DF5,0x45E8A8EAEA4A7CC3,0x60F4C3987B9C4DE2,0x5530A4BA8C604E29,0xC8633404D2B32992,0x0EF021A92A88DAFF,0x698288A1EA5F88DB,0x4B40729F8FC9E24C,0x760573CE7EBCB1CF,0x48FD867C54A50D72,0x232E806F8B871703,0x91BBEF8DF42716B2,0xA4408F61286BEFD5,0x05C107AE0C002258,0x9F18F79B741908D7,0x5A418B6E309B2A1A,0x3EC3AD3A1CE8EA5A,0x2E191ACF2434CAF1,0x085DF7723CD15AFF,0xDAB1E757D9EF2B7A,0xE5B0B75B504E14AF,0x155BA1E6C3668D74,0x26100927C6B18087,0xBCC5F598D690B33B,0x83FAFFDC585E1A5D,0xDD46D0AB7F6E7201,0x158453D0BCFF363E,0xA0AC6D8B3A59BCE8,0x0C2905231BA0854E,0x5130114F6E923C1F,0x941180D5A15EE862,0x5981E82B3A2A94E2,0xE5DF0B7FFF8CE39D,0x0CBDF7CC06AFA3D2,0xA72483138B639ED0,0xEC66327DCA08515D,0xA3C89CD5D790356A,0x1BB8728ED51A4C8D,0xA62B193EA75D1587,0x6D7EA65196770371,0x3519BB1B5144CDD7,0xDD878E75E4BDCA9E,0x83124D1DE6082C8F,0x169136F3807586B7,0xBE638867B9A3CEB1,0xDC7891D93D2F4295,0xD4E5407CD127B52C,0x4D4F83656BA1784E,0xF5534D1546A4FC8C,0x6F11BAB5D27D4F60,0x206246AB5980F03A,0x211F1AE3E1289A11,0x908EFE2802495F5E,0x8FBD0A26B76AC5D5,0xC88076031FC52212,0x0DAD9C3223C1DA64,0xF0BE35AD0EF6695C,0xDC6889C99B7B8F0D,0x8112AC7630805B7E,0x1D0E8FBC52736683,0x0779F054A241541A,0x144F0F7D663A696E,0xE6B5CC19DB596EE3,0xC8E91AFC0B66B5B6,0xCBB38D28B78F31FD,0xA336084455E33C39,0x46D67C11B364DEB1,0x39B35743929E14C1,0x2B5E50984C8F7269,0x42CEF220A0007B35,0x222538677C5B3DC7,0x281FE30391C3FC15,0xC80A206D00D46ACC,0xC78F8E3E6E996F92,0xF0F6A61EFBE258DE,0x470AFBE75FF541AE,0xE8201BD87D813655,0xA3045D1501D485AB,0x17F789DA14482DAA,0x8F4AF77936096D2C,0x313D732F66B4B649,0x8488D65340055930,0x56EF6DD3110CCF8E,0xBECA54DF170EA461,0x1B0C937EAF851C5A,0x40A8616165B3C48A,0xF7E9F0943F823552,0xFA9941542AD57480,0x3CAB762C183CA6DC,0xD34E95A8747930B5,0x8FACCD41A12EB1F3,0x5D2570AE145831E4,0xD73D33B8FC859911,0xB4A87DA1B17F8673,0x68DA199D287DA6BE,0x3D31AA2BAB149111,0x099A5183BD8B7A30,0x04BBAEBC7BB7418E,0x792E3A47C918997C,0x35283A61D5126FA9,0x21D63B90095A87AD,0xB9C8373D75168342,0xEE889F009305BC9F,0x034590ED2EAD2245,0xE29D54A91311FE4E,0xAC2E6E997B647728,0x5336576FB6466DDB,0x3F0AB11B53BFEBEB,0x2E7AD7F2E4F270FA,0xB6EDB335F836D0A3,0xB622E4010405B602,0xDF8208DF52684C25,0x2B878BBE2DECAEBF,0x89258437A5B7DD55,0x6AE10B5A895FF85B,0x335273DCC2808CE0,0x421D1FF5DA3120F1,0x1C365C4383214654,0x384FC8EAB7207B0C,0x327A48157B9118E3,0x442300DC85C8758F,0xB3A8BEBE723B4ABF,0x20E483D1810D3830,0x7957CB6B571E3430,0xE5BC0AA9075B6DF6,0x1EA01C738D63FEFE,0xBC9539FA29A0D208,0x253DFE406A1C50CF,0x22727F1D05DB1059,0xA4A0808311362763,0xBBB2034609E427F4,0x0C61C0D6EFB30D51,0x83B10D7BAEAAAF83,0xED1CE466B6BF66A9,0xB50888CA0637ED87,0x50B6A93C3780B00A,0x6350C44A13C0E9C5,0x1FD92CBF82A2CA34,0x099B2770B3215E85,0xB5E187852F4FEDE5,0xF9731506B32CF097,0x6D177BC9EE996FD4,0x62B635E3BD0643CB,0x72C1FFA1EEE6A13A,0x1FD8D8F01F8E90A8,0x4D2A0423D2E65436,0xCF52471D940CE5FC,0xB10E0CF10FA97F2D,0x2D11711CB0CA863F,0x51E7D5F378E4FB09,0xE2AA05045FD4258C,0xB0DD9BBE6A6788DF,0xB3991FF464997214,0xEB939A65250A746E,0x29F49814EE9431CA,0x2A811A42AFDE5FF5,0xDC0FCC40F128D8CA,0x9FF44984FAE70FDD,0x3A5ADF8CFF4FBA3D,0x88A942FEAB3CF991,0xF78ECCB748CBAC4F,0x314061B33A85EC75,0x43154E86C8104C67,0x2143D424C8FA327C,0x3A46AA0190413559,0x96E41E3E62DC7748,0x4546F30C0CBC906C,0x966D164BB014499A,0xB19E57337B643421,0x6B84E6068FA6329E,0xA29B02DDA199CEE9,0x2508D8D8C28E95D7,0x174F498DC4F4AE54,0xD0B292833218794B,0x9E9DA603F84C72F2,0x186CCB3D0C00069A,0x324A30CE23548512,0x9EBB420C4029A01F,0x48C0E40E68414D26,0x716DA7D6108AB8A7,0x5C1DE709570ECE95,0x2DF135B610FE4CEC,0x37FFC9A1CDB04036,0x58151036026B48ED,0x6D84EC60ED1785EF,0x05797FCB7D4FCD83,0xDB476B4B9635A3B6,0xB6F3264B6959BB42,0xC6E832956A6C3F43,0x538020FBE3DAA246,0x277717808C4C8D73,0x97A5FD5E2F983849,0x15CC8AA4FB1B355C,0x82B57A72F6F956A4,0x588C76C83EC89337,0xC88BF30A4EF43945,0x67203B4298B128C8,0x042692154F2F915C,0x0497AD7E93D2CB75,0xF5178A189F43E926,0x35B2BB0292573501,0x548617FF77D77640,0x484F0FF01645D670,0x4D4BA15E77FAA01A,0xD5E64539976F5255,0x18C6DA62FC10323F,0x6F9DFA34668E7BC3,0x3FB86F45940AE58F,0x44B7CC9E7447F496,0x0779F9B32B3F40C9,0x8477169A7C3A1D9F,0x2176F088B7CBA3D8,0x5399E59870129985,0xBA94058CA22F7D82,0xE00053F74F858430,0x6B94CD3B43884E70,0xC5BC7FE01F3141FF,0x5D20BFDE325452F8,0xCF586FCB721ED652,0xFA4A6D80211EE837,0x4A1DEB1D5B6BD638,0x2AA8FA77823DBE4D,0x41235BCC03EA4595,0x6A50700E93316DF7,0xC3690C2218426835,0xABE645776C71C50A,0x5DE1BF2F0237ABD2,0x70FE0E7EEDB7F98C,0xB6D758FCC9FBB36F,0xC3DC80AD4A8509C6,0x00F9437A4702BE2B,0xDA9C59B3F3363D6C,0x2D981457F98E74C1,0xA0CF6D539F79DFEB,0x75CC30B375B5248E,0x23458BEA2859C816,0x4EF61BEAF82FE649,0x3E00830C54EBE932,0xAD832D7B0FE227E8,0xC843102736C4DC39,0x29B8288859635242,0x361E273D6F6EB9E4,0x10646E05ABCE4213,0x6BE27BAE42D949CC,0x5504205C844D6CDE,0x093317F871EE300F,0xF89212004E94D08C,0xBA165AF4467EAB5D,0x336D4F2131D6AB67,0x08479210313D97E5,0xD98540CDE7729DE5,0x278C3F01B5F705FC,0x49D0BBBF481ED14D,0x79F44B3518517C38,0xD32112B808F03BE3,0xC3A4D5A4464E86D1,0x8D0CF86BB746ECAE,0x094303F337A071A3,0x8518C538F61DED7F,0x2A30290DE20B94B8,0x83862957374C2A89,0x15AC40715FEE83A7,0x5F1F34FD29A301CF,0x9842D6D67DF15A3E,0x6A9CEAB43897EBFC,0x76532990784E7F07,0xDB4C4571A31F7EE5,0x591770670425E0C5,0xEBA9886D8F39B69A,0x36A30B86464B5A89,0xE7C09AB6759B0365,0xA1B8D64203AA7E46,0xA8F228CA65CC3F48,0x85CC2C215C543B01,0x18BFA635A0324CE0,0x3492A7397D9CB942,0x650AA69B98A309E8,0x3DCC2F2752D13265,0x308C263A707082C4,0xB523767380E72D87,0xE4535CAF5D40F6AB,0x98F2D763099FD4F6,0xD0B30F5FBC84EBA7,0x912C1D2D0495EE71,0x41F2748D1BAC091F,0xA5E2DE759565384D,0xE4384B525D10D71E,0xB62A25A4D7FD687A,0xC284BF0C53A4E9EE,0x632FE032FD1C4AE0,0x7A0C761F493FD11C,0xFE92334E9EFF5110,0xDF845712D9BF0446,0x3F8565F0FC8CDDAA,0x617CFED885298698,0x50794FA288CEA852,0x6149C7949CD90D94,0x934D4301111BD1B9,0xB61577D2AEFCD515,0x4DF898A443D5B6AA,0x02E57BC526FE3911,0xB1EAA3BF9FD6E81E,0xB936AACFC370D924,0xE723309DCEBDE068,0x3EEACE12BF5C81AD,0x53A6AA397BF2D4E9,0x7517B29773A5E104,0x01B08A61B6B151CE,0xFD89C0A6B801053A,0x7C5AB5383BE5C398,0x81134CE802130290,0x15B96218CA1D45D5,0x6AAA659EE1BAF55A,0xEAA1D771A577E208,0x8A119ABFB1073A0D,0x776E662016F402EC,0xAA940747460260D1,0x4385D069FDA64EBD,0xB7BA094F415B3522,0xD08BD879E0A50190,0x6BE75E43041EDD8A,0x359979734EDD202F,0x5EC015B1FB14469E,0x1BFA1A23EDBB4A64,0xEDC16CC2087B6F27,0xC304B3499FF5FEAF,0x869DE3A1322BD978,0xE8DF972A41675400,0xADBDAC3B8A7C5B5A,0xE9E70ABBAA5B389D,0xDBFBCFD1A4830318,0x9DB3D2F5364CFE17,0xD2CF1FB281DF5418,0xB92415B37BAF7B34,0x0254549DCF93BFEE,0x073188F695284961,0x700D5E413280A897,0x0F5E6DC1B8C374B8,0x3691FF7F3B45F0FF,0x79DD0618C23CA5B9,0xF31D9514BF1714A6,0x1B9FF08883B57D3A,0x1BCCC7C005FB7B0D,0xAD317AE43F3BE601,0x563A4D5B7B3EBE1D,0xAFEC66845BEF2188,0xD4E4D9EA0667FF95,0xD6B690EA5F4D49D4,0xEB66C59814F5EF8E,0xBA51AB9A0C4CC081,0x0BF901E699E15842,0x3FBA4E3AB49EED1D,0x98DC4A08AAE4A90A,0xB89ACFAD5841FBA4,0xC47058EB2DE91028,0x042B34E199FF38E5,0xAD5C4353000C345E,0x631F18EB5FB5BF41,0x159A3150A0CC3C8E,0x2AFA8D5B928363E0,0x617315078772F836,0x78BA0F0C9BF26456,0x00E0228F5E72EA44,0x8F15B96855FB6117,0x91E8AD7F9F9D2AD7,0x295E4106FBC8C9FB,0x113071591D6F89FD,0x17D3AAB61E5A689B,0x3A5088DF26C8B2A6,0x572E33BC18A042F6,0x943A9FCC8DFFC19B,0x03477D75442CB514,0x4A214FDBC66D5605,0x52EBBADD1A3D5B2F,0xA4D0151A4AB3A0A9,0x0BC38E22F0346CBC,0x6E7B1FEF43FA26DB,0x66CAE655399B0B68,0x23CD010863EBF765,0x1FF545AC98CAFA07,0x7EBA18FCF5E51F2F,0x24385AE0EECDFDE6,0x44D50BF36873EF26,0xF533246A97C61A36,0x783BC65D426E6E4A,0x9FA1FD5EC9A3090F,0x030AC3C554097990,0xD2301220A3BCBCAB,0x9AC0B0AE785D9E5F,0x1C3483F15F786392,0xC2AE419AFDAB265E,0xF9341AE1A1C31894,0x4BD132A44955679B,0xA74588F6A1B9C5EB,0x441C1E92CD61D953,0xF82A6B63C3BA4EAA,0x93D629F2D28FF428,0x67DA5A6C8B0C22EF,0x29A0DF4DD3FE36AA,0x81231AB783F855DA,0xACB53292B05D1259,0x7EBF590E29ADA409,0x1F3F1B1FD4A4E20B,0x4E0599AE3628FCC0,0x12529EC53416FBA8,0x5013E5B8E9DA0D3B,0xCEF4892471944428,0xBC12C20EAC2C6C35,0x953FBB1F831A183B,0x40A6A50FCF81F0A7,0x31E3F2F579FE717C,0x7DB4D5A35349E8A6,0x1C702CD7423E33C7,0x6461BA664FEBE8FE,0xC1051032E8480EAA,0xF6D0975CBCA17A13,0x2B8DFC319DEA3667,0x6683B2DF9C3894C7,0xDB9E6D5984675963,0x1A9F791E22BE374F,0xB60F8651AD2A1D6B,0xD87A26FD2F8DFE7D,0x64F87423F265A1FD,0xC8FEC334E2092CE4,0x4B88216B29F7C194,0x04B35B8358F2DFD8,0x4029BF54C84011EF,0x6813BD325BEA3C97,0x97D08F4F6401B5FB,0x318AE0D791F06B8D,0x4ABEF38FE7BC8047,0x899BCCAC5CC60EFD,0x6E722F81FE6248C6,0xEAC10771FBA271DA,0xE05220E05B5053A5,0x2F5AF3267B626F58,0xED42E36A44F2419D,0x37033F565746C8A9,0xC7DAED58B92289E6,0xA102A4EDDF1A2E2C,0xF2EC7A10BC40B677,0x19F3E3C1C87BD1A3,0xCCA8BF10B134F6D9,0xF06C7E422A974921,0x94CA83B54B781960,0x322D9DCC0523634A,0x387D933583E61668,0xAF1C580F649ABE32,0x680998FC1887D9BA,0x467641F41ACBF97E,0xCEC7265422E76EDC,0x201EF9DD7C8B36E8,0xEB08D9DE53EAFF2C,0xF2E82CA754567906,0x7EBFBF3A8E19488F,0xE6338680A8323B94,0xD3CB62378A883E98,0xC56755DDA5318642,0x5B9176E2DA6335AD,0x96AB8A297CAC5215,0x8478CDF5EA6A4536,0x007FC28F3E47B849,0x23F2A7EFB7E586E4,0x75BDB71F6B0A35B4,0x89BDA0C32A8AE093,0x4F7B4B6A6D4F91BC,0x3CB65A9B86BCD974,0x32EEF1355592BB93,0x69326EA092ABBB1B,0xB756042BB88242FB,0x32137CB6C19DB982,0xFE544B89AF547030,0x139E162E33F3B851,0xBF1E3B4814A4157E,0x3A9D2FF42CC9A31D,0x6F6CC996DFC97E82,0x6DC1A81F8847FF49,0x3B176FB7EBD0515C,0x1D6E6C8032C45EA0,0x8B8EE70C3E9CC183,0x389D9E76757458F2,0x51FFC22438727DEB,0x2B2AB36D6F5E9192,0x256EB59429129BF7,0x6CD210847786A7C5,0x9ED80B18255AA607,0xF178E8ED6891A0F3,0x691E6DC1F5B57A7E,0x2A353C1E8052B593,0xA62F282B856ADF39,0x9AECCFD31010DAD1,0xBA3F245E86C6DB80,0xC5DC5DBDE9DE4B1F,0x09EBF261011C5A05,0xB939EF34FC41DCD7,0x0D6F77E583DF261D,0x31D0384DA87AFEDE,0x8E55CD9D26AEEB99,0x17F94EAA48746173,0x7323473B25371131,0xD2B304F44FD8CF85,0xA509328C1DCC1573,0x3565AA79BC40F704,0x25E5CC8FA0EF8FC2,0x539EF1A7E77E5E2C,0x282ED759DCEE2397,0xE233CC4D7EE9FCB4,0x246AEFD9FC8C7219,0x6C21AA278F622943,0x1CB938035AEFC810,0x64734BA3CBD0BDEE,0xE9125FC9B7682543,0xD39C8F752FA16E45,0xDC77F293DBEEE552,0xC1F5D65A245417D0,0xDA78BB82A7777989,0xAA5D19D270071B14,0xDE9C47F170B4F9EC,0xBEBC2B15F5128BD3,0x728D2395473FFDBD,0x21EAF6151B938212,0xC684088334D91A7F,0x6AB68A37C8DA4D6C,0x232CF26E370438D9,0xB1D924923E6E224A,0x0626B929D0C7F51A,0x464DA2C5D1FABA3D,0xEE43E2498118D941,0xA972442A90DF86FF,0x30AF8512BAB0B24D,0xE58805655B3875FA,0x0A325EE1C67381D8,0xE6614EF5A13D229D,0x79FD5CE190D23016,0x1F153A4B4570352A,0xFCAC87E9333C4001,0x300B7EDE814BB8D9,0x64851594CF6F7A5C,0xC28885A8951FAEDA,0x7D9DE7C399DAF39B,0x06D4D398311D55F1,0xDDA86B2C8B97A06E,0xC6508640702BB1B0,0x81754C3532D59F93,0x803B857A4353DF4F,0x72410355FE44D30C,0x5D6FD6F5D26DBE11,0xE2394BAD34516387,0x2D99D93E48CA1647,0x428EF044657CAF03,0x81A22BCEEE99B074,0x70D42665F817199A,0xC035EE59D1FA9EAA,0x706E4A836AD792C2,0x672CA9F40490B036,0x8CEE10029F6D516E,0x34C47F1E68FFA4C6,0x821D5E7EDFB504D1,0x11EE8B163712B33A,0x2581446497762143,0xCE6FEAE8C59F4C45,0xAFAE7219FAE28CEB,0x5749DBCA5EC66A99,0x311D7CF59FB52D6A,0xF284C234ADADE41F,0xD58EC303AB4E1115,0xE1B90569E6643D27,0xC8624D6F219B36C2,0xF89E0413BCEC0D4C,0xEE7E76419325E3C5,0x5D38EDC6EF5F6488,0x7E5669381E6AA538,0x150B61E970BE58D6,0xEB38BD847E8921A4,0x5B2CD7613CF2643A,0x831AA60B9F2810B3,0x4C16184B32C58176,0x4BEAB668C3E68C42,0xCFC12D33046D7329,0x78F24DA8B7C7DD03,0x81B6F6A4ABFD876C,0xD8C679E2BF3242F0,0x30FC50B0EF09CF18,0x131DBA63203573D0,0x8AC1697F234EA1B2,0x3FBA2069165B7ACA,0x2CBBB82B9E1949E4,0x1837012281DEE26B,0x1046602865BFE682,0xC07924CE9EDD4DE4,0x023C1EDB6C11A855,0xEDC9B3A67A9F9FAA,0xA2DD1CCE186A003F,0x85BF6B1C89E6A909,0x1C8F7537E2EF57E7,0xC29B66F02656DAB4,0x82C22A60BC97F1AF,0x74B5D7E93CBDB9DB,0xA5EF2F5EC7E79063,0xB004232CF6A6B928,0x794DC2F9E5739F84,0x51B5C8FF35EECC3C,0x73A75C4D9A0D8350,0x2F708A2BDE0E2C7B,0xD8A11C40A8DC9D3F,0x23843390AF363AFE,0x115C0EE0DC8754F1,0x11E2C1A737ABB0DB,0x8C046194E4054373,0xB8DC8A2E31CE92E8,0x7E8006A147A62403,0xD75F5D08F2A2ECA4,0xEA253ECA1BA9CC36,0x3F31391843438642,0x3FE884D7C9DFB3A2,0x745A90543FAAF2A8,0x4541783F8AEFA0BD,0xE77211EFFF05CD6F,0xED8079E045F534A6,0x9F3B1AFEFBDAACA7,0x1A3DCCA2490A9BB1,0x58BF0F1905E89F8D,0x173AD9A3368C0209,0xD14281582C3A1B64,0x385F7D9687983786,0xFFF419B64C975240,0xE7326E00ABCDA3EC,0x0CD805DC56EE3DEC,0xCC42D14C1429F646,0x18DD78BB3B308D41,0x65FAB43B0092A47C,0x6A2EB89CD8CF1E56,0x98ECD7450A7EF4CF,0x15C3B0476D62D0B4,0x18082B2FA9D138A8,0xBB979DC60CDB2171,0x8F5A5A0CA036AAB6,0x76026406FB9FA5D1,0x5329356EF7880F55,0xD1BFF305CC994E3E,0x3D5A45CE52F27558,0xA73A2F9F624849E3,0x66C4EFDA7540877F,0x54169CD0015F2779,0x002121230E35631A,0x41422BA1722B40E6,0xA7881FAA6BC98BAC,0x746F43A7208B5B43,0x03310BFC5297F298,0x4ECC015FB0C9B6BD,0xE53C149CD7ECFF9F,0xC2C1132E664499C6,0x631C1A9385F4DE2D,0xA865EB97B75080DC,0x100211F9B5247ACF,0xF1AC0DA0D8C00265,0xC314051F1B57A87B,0x4D56B12B7FB7B876,0x300F273780E4E6CB,0xF5976F78A03F1B56,0x24F289AAB95D64E4,0x0DAE308307FED8D9,0xEF3BDC8D1C7EB530,0x2D315F8950FCEB21,0xE6FD49CC9B0C24FB,0x3A7E9BD5EBB9FA13,0x8BC3D7CFEB722AEF,0xD442C445A486F4DC,0xBCC6FCA8F77396C4,0xE37C56E17D29C05D,0x1709982415F51747,0x88142A6840C29091,0xC6A23BF25F5B00A9,0xD43A227A690F3654,0xBB6AA1B1F66F0A5A,0x06AF2AD2079270F5,0x6BB1EA806D4017FD,0x6F652CA4269718C5,0xBACD5A5CDEE29F3F,0x44268F2A8DBA5A71,0x54B05C3CC399BFB4,0xBA4C452C43340C07,0x6C0328697BD79896,0xE0B286D1AF589C8D,0xA49B613CB312E7CC,0x05D32093A8EFCE8D,0x690F55AAC450310C,0x177D3ED74DB744A2,0x1FCF8BE12B9A597B,0x7C45ECEA6DA88BEF,0xA9F5B60FF391F46E,0xB0684AD2E3DA8FC2,0x7769D189A4A9A74E,0x82D6D8D379E80E53,0xDAD73976FAC58D20,0xF502F96F591ED74D,0x47AB92AF0FA51645,0x8E1CE6CF120AD6A6,0x4A14671C92E05486,0xB716E8681CBAF0FB,0x8D9B068C623880DB,0x44E478BB7CDEDA96,0x874162106E1D9182,0xA8CBDDECB817C3F7,0xD16813188AE54845,0x9A94201046F82D7D,0x7A0C8C906290CDAA,0x3482868DB2E9B77D,0x0FB63A30D8D163E0,0x52C420A92E2E1C56,0xFD98B0CEDED352E9,0x8523778FE53A813E,0x523F73399B1D4D32,0x29C9F0BF1948C896,0xFCDCDA181499C6C4,0x5D87129BB0DFC5AD,0xFBC0033614196A27,0x6C7F4CFF883692C2,0x90F17C0CB3ACEBFE,0x628388E2A191076F,0x281252865828FEE1,0xE3DE2B5688761E9E,0xECD9605253861757,0xEC3FD1A8098937F5,0xA1BCF160265CCFF1,0xE62602F2E8A524DB,0xB58CC01927E2A405,0x72D8F39CA9C337A7,0xFBC675DBC89D95C9,0x6633F9B775A33983,0x9BB9AD0F26279E77,0xAD16AB9794DB2A0C,0x4A23C50C7743172C,0x0427B4671E1D1484,0xACD5A853B902FF42,0xCF247D9C7382E831,0xA9C13EC7E057DAED,0x274DA82DE99AAC8B,0xDA7DE389836DFEF4,0x003F947B0FD3AA97,0x384EB0C09357C742,0x80B21442CECE5516,0x5903112424325827,0xF33313218852E4B7,0xF6BCD44CA943E1AE,0x60455C8C9A006A9D,0xCFCB7811B17DD7D3,0x5C37A92E60D595A1,0xF6BFA8A29C049A06,0x3D5340740FC0FF3B,0x3CE6D3B2A3C6639D,0xDB801E245F5ABE8B,0x96871EB5CC436AA5,0xD6F0D22813DDDB16,0x40A3A58436AB98BD,0x6D2E75AEC7761CE0,0x5E08B89471BA97A0,0x6B9894C3F7DA84F5,0xED23306FBD6BBE83,0x3CF3B20787983507,0xCEA95C22513D0088,0x76A28548296872F5,0xCCA87A62ACBC7801,0xBD78954E63BFC3C5,0x67F3448430BB6FCC,0x7F1F640943DA7BBA,0x6A3B4C1A8929D9A2,0x41F3D36C54700EED,0xFC17D85B23F4EFC8,0x5FA473332FACB57E,0xA54A0831B5524F50,0x998EE3E21139648E,0xFE67CF03AE44A660,0x67542DD58F5DBA2F,0xF48C894C24574CF9,0xBD47C71647E43883,0x6D73F39F1B28861B,0x6C4E2CFCE9728F64,0x147F2A376971514B,0x3FBF2E0FF03625D7,0xB318B1D423576709,0xF977C802F98B5692,0x276B532BE0547CBE,0xF36D98573CF164DB,0x710A845AECB2E235,0x1264347D90073A88,0xE132E58D85BC9F6C,0xC1B44DAF5DF851D1,0xC7560BD4859DEFF7,0x5FAF1F43CDB4CE1A,0xC71A5CEC0F0B31FD,0x3CE14A8B80768633,0x7602E5BE9B84B79C,0xA5C9A141CAE70092,0x94212E57AF651B1A,0xBCAD7F50187F821C,0x5442E316A30A9BA4,0xB1933286641FE0D0,0x5C5285378F350142,0x6E7029FEE3006267,0x5D8BD01C146D7BD8,0x3C2D8E452E0E859D,0xD1AD4B09FDE691E1,0xA22E05BC0F83B64E,0xA894C0376A66E49C,0x1512E4C4F8E6BAF6,0xFC76EFE878920134,0x184C048115E96AF4,0x5E6F8B5ED7841ECC,0x62CBDCE094C4110C,0x4399FAE5D0A504EE,0x31DAC04584709C63,0x4B5944608E102DAB,0x8D93E29D3BDB6713,0x6ED0BFAC766EAC3C,0x2F5839802BF8632A,0x8DFA98D3DD1E3B47,0xCA0C016B9CF7CEA8,0x7191CD0E5FCE3BA8,0xE6E5225111B090B6,0x1D4105D251205554,0xC6CBD76062D6B2F4,0x2AED5925090763BC,0xB7D3BEF125044961,0x95934329620C60E1,0xCD921DB47414A45E,0x744C7FEBD62C3616,0x01072A5AACA99314,0xF8504DF41F4EB13C,0x9D1186DD45B88B66,0xAB712D9D734E22AC,0x0E605530E43D9397,0x1551C45A0374870B,0xB48FC82558717AB6,0xEAE838710381A2B5,0x831438280D1ED9E3,0x521D5789F2C997A3,0x855FFF289C06D224,0x2F79811586129130,0xBE8A92BB0D944309,0x93EAB03C25273582,0x6762DCA5400D7468,0xC89C5F1A9A48E3AC,0xEED527AE127C8959,0x1B123A75AC70B352,0x92D1A0A3458F8A1F,0x774F49605B3F07A4,0x862B3E6007C18859,0xD7AC4BEFC9151F68,0xAA52816FE2021083,0x478D84B878FA49E3,0x5539F24F5E0AA48D,0xDED0E8E1FD160762,0x6D7B8989EE979E5F,0xF6DEC1CE8FD6C217,0xF674E93BF088C2AE,0xDD8E805AE73FB7CD,0x70908B39E07DE15A,0x5566C5C63C5D483B,0x24322AC56CCB2C14,0x881D1E3F7EC83DDE,0x53A43333E5190CA8,0xE2992A7C7B91EB51,0x6231152A7017AF97,0x81C555D7FAAFD513,0xDE4837E69C6F4432,0x2DBA3D0462AA975E,0xE3F3F4B78D94B207,0x394D716EA2AF203E,0xE18BEC91E565173F,0xA59073A40B58D813,0xDE60469C657DB1D9,0x4F59B2E02E1AA00D,0x3E9E5CF02512432E,0x92A10A138437284E,0xD0DC1BFAB492AF97,0x8D0B67B528BA1EE6,0x44E61B54FB5305DF,0x349155EAFE45082A,0xBD33AB5401CDFB65,0xF1C5D12ED23923FE,0xF6A643C9F3F5C212,0x828A75AF80FE14B5,0xCCF0C282B88FEFC4,0x7AA67776AA70A30C,0xB9F556FB33F42AEF,0x30B54F35D298D677,0xB6E72252E17F0107,0xFF0436402072254A,0x45A588B4192D80CA,0xC0FAACEF4B796828,0x99F7E85234FBDB7B,0x5FAB946A86E93BB9,0x1F53A91BD8C507BE,0x81CA1FF633579949,0xEECF1361909B029A,0x0FEC32B18C1F4FDD,0x8A3C84883FC3E6B2,0xF899E61E223CD046,0xE81FB60A52F5DBCA,0xA071D349A90E14A5,0x45AC38BFE24B7005,0x03AC4E3FD875A9EE,0x7BD1BDBA91D2E3B7,0x1851A339306DCFA1,0x786AF5835D7438D0,0x2E1CDF6CD80CA1BF,0x03E160D2DE7828E4,0x612096A4BB1031A8,0x17736DA9185E3388,0x2CBC17EE56951E04,0x87A6EB8692A8F2D6,0xB0C65AF988AE224E,0xB67D6D2604C659ED,0xD06718CEF5168C21,0xF4049B5B5BAC4EA9,0x88E3879AFBB22F24,0xA115F3DAAA2628A0,0x5AE493645BAE1D08,0x667995D55DFDF0C1,0xCAE0BF0FBB4ED4A5,0xB80F7C6932602839,0x94D4FABFA87E3750,0x08BDD53DB8BF44ED,0x8EA19317207A228B,0xF34E615EF0C9D8F0,0x0A505CC11EC18E23,0xECC31369857B81C1,0x351ACA27291702E4,0x86ECAA987D19D0A5,0x8BC6F5AE55490D84,0x5C88EE0C2859B8E8,0x692C4DEF5779313D,0xCB6F017770CA8B15,0xE2240011CE01862F,0x03B629F0AAD01456,0xE3B8112C4D0BAAFE,0xD9B8A3BA9834ADED,0xFBE5A19F2612A6BB,0xFB0E8426B13C3BA4,0x891FF6B38893EDE9,0x30EE72278CD5A7FF,0x923254C6DC8213DE,0x8B89E2C641DDB245,0xE309AF4B48D70BF8,0x010EE77A4DD5ADFF,0xA8DF23B39F17DBF0,0x97E66E3F45B43BFC,0x153D98EEF6F6C480,0x28DBAC5B1C857E7A,0x781357916A9E5FBB,0x227D8467FE5702A9,0x6228E7E19605DC8D,0x061F442940EFD6E1,0x8E7DBC800A87115C,0xA0A40BC6F24EF438,0x6FF46DE56D0E5EDA,0xF0F4D3D38C470808,0xF22C756669B0840F,0x7E31BEBDA34B96FE,0x620C4290F907AA9C,0x5BF95EEED926B1ED,0xE3C4FBDD1E4D0B83,0x523B639FAAC9CFB6,0x7326137732D4D3AC,0xE9B086FB456C04C8,0x946BFB847B02D1B5,0x004574D0D94D5EE6,0x529D52EDE989DBA7,0xD6ED46377108C296,0x535FC53ACD307042,0x773995D653291C72,0x1EFFEEF9B61FACD7,0x9AE5C73F8232C663,0x1585C28F29C646CD,0xC8431DD7EEF5D7B9,0xDD84568B2064FB3D,0x3A8AC8F5153A2B78,0xB7AA399B1B920619,0xD226EFC8E0D1713E,0x0816324A98746411,0x0660030E02CC2693,0x041683D6F851F677,0x3802630482C6AA98,0xCE4DCE9408E04B8C,0x5AA2375494872A5D,0x96866C6B1EEFAC2D,0xE3DB3A9F3927CE91,0x52992263E4F88ABA,0xB9BC8CA2860A8A1A,0x4DEE15135C24855B,0x1AEC3C2C7F6BEF79,0xB81333238F136186,0x7624136D4B570DE6,0xD53EA12F1B8A05A2,0x76B22B312D3E1080,0x5F7AE2ABFF420138,0x376005F8C05C22DA,0x1A58C7358FDF75C1,0x276EFE8FB3E3A914,0x7415A8C9B49DF74C,0x04DF6C221D8B7A29,0x16A5234FFFDB0244,0x1235A2B9688436AE,0xD156D894A2356E88,0xCC23A76A8B6CD2A5,0x88295C0C3315F39A,0x7AA34E1CFFB64CCB,0xFDEAA5B4FFDD20D8,0x5F7671CF4083F23A,0x53640F2FD3B28E2A,0xFF68C566E27A4B40,0x63B1A6D00CB68960,0x8C04D72095D19B31,0xB2823C2FE1E961D0,0x2467C2DE1199F634,0x4E43F7CE97975A75,0xCE4EFCD45B824A31,0x9056E5BACBFA7E0A,0x7F596CA13CEF227C,0x96F29F11E4888EA7,0xB5C3F0C17B93DD3E,0x3B9574A5E745B648,0x03D3FA34259045DF,0x65C0E8C349CFD6D3,0xCDF9DE97E0AB0FAD,0xFF899DFF45D8D826,0xBB28EF5E20C171C7,0x1299FBC527541412,0x4D349F663FD15D35,0xB347F849B7BCCEA4,0xDBA3F21F014D548D,0x6FE695E5B1B225DD,0xB5BD0EFB36FA0F0A,0xFD0ACBDFB6AF4F21,0x02A57CB23618C351,0xB13141B85A76483E,0x9A4BE4051B7D8309,0x80690787932F304B,0x97C7350005923C92,0xF9957337C574B2EE,0xC767725D9515B6FC,0x97CFFA8122C4844F,0xC0AF578587772225,0xAAD151794CC58EB1,0xF5EE367A6586840A,0x910853C139263D7D,0x2371ECD42EC75019,0xC4ACCED5A47FC829,0x3479A211A26D5818,0xE1602B65C77E0DC4,0xD7EDDEA79156C1D2,0x6C30B084F8CA6158,0xBA803FC507F6928D,0xCB0CD9EAC0FC7ABD,0xC9813651949EFAFC,0x0F8799A166D83DA0,0xCE73C09E69A5E58D,0xC0F541B779427EFC,0x4158B422D9A8C611,0xF25A406889E4520C,0x179A54ED8DD2CD06,0x6776ABD819E4AB12,0x06ECFCACEECB1B23,0x97FFBE8F89E8B171,0x3EE2038E33C65883,0xA57D8D02B69FD949,0x433EEE2D8D10E20D,0x14D28A1D3D115CF2,0xFA787A54089CE751,0x01AD88A3AB8247FE,0xAB0BE171E99FA2B2,0x96E9C983255CF5B1,0x7225FB5AEA79AF72,0x6F4158C72AB7F38E,0x4431E2EA6BEFC3A2,0x3A0560AEDD701865,0xEE1BE74ECB0E8749,0x90B26AC1637CBB08,0xDBB0D0BB42203082,0x4230B3E020513572,0x24B2407F91E95EC0,0xCE18B2D1CF57515A,0x72931E22B1D74FAD,0xE32E4F71C6B9763F,0x13FE1E5F65B9BA26,0xD77D8D0826587F7A,0x34A2BBCF83E54549,0xAE5A07CF1AB8F6A2,0xEFE5E1D2AE236EEB,0xF7C60B36341DB6EF,0x622AF3B72A15E597,0x93C1B37166485904,0xCC7F1BB8CBC35FE9,0xB07F10B14D59461C,0xF18CEE0BA189F586,0xC7CD566304732ABF,0x89B7157A13E62DC9,0xA85B5654AB9E6ABD,0x1506A2CB88D371D9,0x9C9FBB947D9CF1D1,0x9760CCB75850B93D,0xA8A55C7F201F0D0A,0x0FB0C559246C6978,0x8366EC3000D47F1E,0xD433FAB0547F20B9,0xE0075CBAE2D73ADA,0x0B6126774D5A6A8B,0x4A6E0C3962B93535,0xF5FE9FDDB55D72CB,0x388CA57830A291B7,0x55E291B38D48A19B,0x63CB77E0F17417DC,0xE0E536518DD43447,0x4D9656B0EB219B00,0x0FF9F6802BF937C4,0x791CD1C8BAA2C2EC,0x43089414693FBABF,0xCE82314A6A2E140B,0x00B497F13B5A165D,0x34565405E12FFEDF,0xF50DBF2C1198AA0C,0x9D18B3EE347BCB31,0x7BD8E9855C7291B6,0x7146040C6D63113A,0x223978ED301ED257,0x08BCB2EB1DF37B01,0x412A3DED997081DD,0x1B1A979D93784717,0x2FF948097CF233B6,0x03A2CEFBEE90DA5C,0x47DF450800C28C6B,0x2D7D26730C2961CE,0x34071EB6F186D846,0x7B1702875EE5E4FB,0xEA55C3D147154C8C,0x0E6FA5C0B0158404,0xFD1DF31B2E6C58C8,0xBE7FD72DA28FE508,0x591140F75C754566,0x7EBE83A761BC6E18,0x600203EFB23CD79B,0x93EA0B1468375159,0xE44C4D02C84DAD6C,0x15451AF79530F8B9,0xFE569B45D47FAA36,0x9CE2FC8BA470B046,0x9477F7466B43E5C5,0xCB60CF22A2F4B428,0x00C0DE368E714136,0xA3CD8057775EBAE4,0x54E21DEA6D12F178,0x52A1805FF1E6F0DC,0xC25603FD6EB4FFEA,0xFA10DE2B1E67CCDD,0x07BBA4BF4546C558,0x2548E15D270BDC64,0x2CBACB865A9C16A8,0xA14DABBFEF4E5B99,0x5AAB97E9C85A290F,0xAE19819A9EFE0FC2,0xA55BC320E614F5DE,0x003CE4CD7364B885,0xA0EC3D83966CB771,0xF4CE68B212B0F8D2,0xE3EE0136E68F7169,0xBBEA3D08800044B1,0xC49D4B1801CCDB9C,0xB5C0DB8354EAF83F,0xB1AA3ADB86AC4D68,0x0DC4EAC799D9E96C,0xF7084297ABDC067D,0x9E00F8A1D7FBA835,0xCAA260BE4650E5C7,0x40CEFCEE277C0B92,0x828C97437495E1E4,0x5CF7E1C823FC3AEF,0xB98987812D2C10F9,0x01FB9EF8C77930C9,0x97059783EBBE1696,0xB0EF97A48F44FEA7,0x777C5C3F17A1200B,0x7F2AA67612C9D8CC,0x98D595445E66978D,0xFC6F99910312CDA5,0x1687CC8826BA7C2C,0x548A615F4DC52F72,0xB082ACFF9E879DFC,0xEF469F5FB00A5EE1,0xF0D0F4D9049E6162,0x0DDC46A948B8804E,0x055BFFC9B352ABCF,0xCB60EAF4FE23873C,0xB5D65240B2C735EA,0x07794674A8F5D317,0x6E2CF0325B9E5880,0x9A015B6A863EA9A3,0x9D6E25447A10FE29,0xF5C942DAB5ADD3D5,0xE471FD6D2DB9628D,0x641D7D6E522D4C20,0x70216B1ADEE168AD,0xA0766E2CA68FC2DD,0x43B40FAA17524FAF,0xC7670635E01477F6,0xCD3B9358552717C1,0xF449E7CB18317CE0,0xF478E163979C040F,0x4D7F77D355030A45,0x0249A5EBB355A02F,0x44B24D0C57AE873C,0x3D6D4E3F41FA4B53,0x4E3C12DB0B36E2CC,0xEB73ABB32A36BACA,0x228F30B80605C735,0xC34483584F68C8D4,0x9783FB567A3E89D8,0x8BDC71623B67C513,0x9C81B90A3DA3E757,0xEE6C33EFD60ABB67,0x6F11C5A6C675655B,0xEE9994A5EEEBC674,0x84F32F4B7D20B952,0x98BB7824097B2F14,0x97F7A2B79B8BC0C6,0xA7707D46ED0FE17F,0x2EAB00B1831A1740,0x22CBC1474B69EA31,0xBA74D1332C1F0C94,0xDC48C83102DBD681,0x4A229DC6F9211973,0x65BCD1E9656C50A3,0x233477F7090E05F6,0x5F82F3DC0F6ED7A1,0xBB8DB48FEA9E9901,0xB379D00FCE9F2BAF,0x6227FFF05161186C,0xFF435321E507EFD8,0x5EC2402DFFDD2E49,0xFF60FE723487ED31,0xED4AF280BC7764C8,0x09730FAC0F0F7FE0,0x904A83C4467D1E1E,0x1D12E6F64C9330D9,0x91B61CC7A3A4D60D,0x325192A5826D764D,0xE86CB4438BB4543A,0xCDD999973038860E,0x10BED650328D6AC8,0x87ECB18140172D78,0x18440A5D087D1A35,0x87B2BE7347A143EA,0xB4AD7D7289FC3D76,0x8648F236816737A5,0x5AC182218A432ED3,0x4CDEFB40C2342EA5,0x02173C26E955C569,0xC363CD7833A880D9,0x5DD872877C1A49FC,0x180C3C7AF15BE9EE,0x60076753BB3CA148,0xB22C8A66BE4F75EF,0x21E036160A34F0C4,0xFAE077005D8971E0,0x30F0E17E04BE8B16,0x9EF4A8B63572474E,0x7692EA26EE068DEC,0xAF0633C2B65E0598,0xB1B5C8E5F807A5C1,0xFEFFEA18624A1E6B,0x30EA23C820DCD31E,0xDE7144AB0218D0A2,0x3B7C7C7D87A5293C,0x7E6C142FD414A740,0x67B74D3CA5E04821,0xCE8061E3BAF53A81,0x4E073161E404DF03,0x0EC3F349FFC48257,0x23569978417E4FCB,0xE9E8153DAFFA5987,0xB0A05DD83B45ED37,0x5E0FE9235483F926,0x7049C025B0B1618C,0xA80277910B3E7940,0x816EC74CBF67D97C,0x0D4CB58466DC4F39,0x71D67197AC09C2BE,0x4D7D36900859911C,0x18606D2B6A150AD4,0xE0032AB3AA2A58FD,0x1044F5565FE33B65,0x4D214BAE91050E69,0x88A1519E2DFF4315,0x9548A0D0F8F1A31D,0x33FD45CFD68BFD3F,0x8FC42A0CADDC544A,0x96A6EAEA1DCFD448,0x9C9B18F754288426,0x94E434B106976245,0xE8A375AEA5BE7ADB,0x331F36F7CEA67D8B,0xA575D616625DC73D,0x25D3B8C52614A070,0x2D941BE0E68F8BC5,0x97AD5397B5B81B4D,0xD8E20868A822FF29,0x17FCF9ADA9541134,0xB2DD5D4287DE205A,0x512842282B62CC6A,0x62A56AD4414275FB,0x74160D1C801183FB,0x234EC1452E941018,0xBAC680668E8097EC,0x4D45C5076F9D90BF,0x5F3F043322AA5AFE,0x7486FFF835274572,0x54CFCD6BC991ACB0,0xD15929825CB1B20B,0x20B08D64D79387E1,0x6EEC74C77505AFE9,0xEB04D407EB6BC926,0xBA8899FF34C2AC90,0x77D40E62B2ACDFE0,0x4E03F80E2A1FA6E9,0xBE733F57BE94DEC3,0xC435CAB3B8FC0943,0xDE9F99D40D4A1CAD,0xC206AC40D7C747EB,0x673AF54A29123C98,0x74E792CFCA5C5549,0x09D1F39BD5A8B42C,0xA54C03C6C73EE065,0xB77F91D34B9AC7CC,0xBC6DE1813760E331,0x08175AFCF15D2DDA,0xCA71F02130A4D9B4,0x3FCFBA5D787CA869,0x5C12C033B31FB08E,0xDEC79F911DC03870,0x88F4991B46A5CFD4,0x86E8B73CDDFB6720,0x856825C26620F07C,0x445CBCF9EA2527B8,0x07F5E830EFF3F501,0xB323A749CF34A5DB,0x0EA427F149A5DE50,0x90F0F9E5C556186F,0x113E5B28B7047ACE,0x6583794AC74E2463,0x330457E0827907A9,0x34B9D180718740D4,0x25ED3B56D185895F,0xACCB3F802C982635,0xFA3B0BFAD1E89242,0xAEB202AF8C70EC0B,0x1008248DCCF7E908,0x80C0201DDD3A3C5B,0x5637AE72698B91FE,0x5EFF6445875C5749,0xC443555590BD70AC,0x2E27A0FD57AFACD8,0x10635CF70F96FBA8,0xF2D5FA19B36D3E23,0x866DF1EEF8EF925D,0x1F2F8B6E4CF3918D,0x30ACBB65E7EB73D8,0x192CE3B86DA48822,0x6B9AE662BB6F8A93,0xE223A73DAEF10788,0x68DF82D81294141D,0x2B6909C4B775EF1D,0x4200862E184EF746,0x260B78F9840BD861,0x6C30ACD4404C7BB7,0x799AC613B03AEF8A,0xAFDC379310134B20,0xBA5B3D54BC9B8B98,0x74C04D76F9004535,0x74A0E415F5955F12,0x1BA4579393A6A989,0xA506D7F4A03A5460,0xF452656FA5D0CD4C,0xE3582E1BF94F2C4B,0xC4F9D92E12E31467,0x65E4FF01B07F330C,0x7C635D73210C7FCD,0x8F3DD2DFC07E4CC2,0x9F8F2E76F9A3858B,0x5C97C2CFC21B4063,0x9C0354CD2EE15014,0xB55995291A15EDB6,0xC64AED1E4C0E7424,0xC8FEC74E722B9364,0x80F4281C3BC4BE99,0xE209D474D5BC293B,0xF1F7B0BD0F4DB246,0xA37BA6826D7FF385,0xD45A713818AF0A2E,0x45EC10EC67620D84,0x97FA80F616F6AFA5,0x84AE16039EE0AF1E,0x9B8B0EF2CB977F5D,0xFC8913802B5050D3,0x825773A5C0EFAD45,0x89390BAE0FB6B40C,0xBDBE871143F088DA,0x1C92388488E70EB4,0xC7BB22B151DB23AA,0x31E0FED94D56D9F0,0x7A520678F4F69884,0x1D15E884890AFB48,0x250644A152F4C2A5,0x398C8106FBCFB93E,0xB74A14EE0D7053AD,0xFD47ACD8517EB536,0x495256FD29EF2BB8,0xD2CC05265F9A0DD6,0xAFEF90F77ADCB6C0,0xF012B68AE1ED1E0C,0xBF42016A7C432F86,0xBD5AFE87F4D7E650,0xFFB91FF51C506C33,0x80B202A8EB752164,0xFE2808AB9BF422E6,0x810F7F6741B7732A,0xF7B7DEA1D1BE3EDF,0x53C76D896914BF99,0xF1A450BD2D9BE1B0,0xE10C9744B63E270D,0x443DC5EC5FB0BD9C,0xE6BA1B7C3B9C4EAC,0xA6DD560928823093,0x3F9190139AB05E69,0xCEF986E992C32A49,0x588F459E91116949,0x118CC1E0584E75E8,0xAA46B1AE1E77C87F,0xBA8E05BBA88721AE,0x93BA1CE1ECEC4EE5,0xD0BFF0897DBB25F3,0xAB89E35DDEA8EA71,0xA6AAA7996E042A94,0xE6F7AAF1ED8ED21B,0x5FBA84841E7D4115,0x2994A365490271A1,0x6E70437A0723C565,0xEEE4B31A6B09DE04,0xCA07081781DB2823,0xA6D41AD9C73EBA1A,0xFD8B3457BBB6EEDE,0x2D4E583EA53873ED,0x97F96AD44E275E38,0x6BF65A9A921C4D70,0x51DE00A968637DFD,0x3047B30BC6C87BFE,0xEF1F8B74E745C252,0x4D2AACC1FC57FEFC,0xDC1ADD59D8B89635,0xA56B18E6A678BFD7,0x5924B17506F36212,0x137FA81D49008BCE,0x5C06ED8D69099704,0x94C38FB408B79D6F,0xC80E34E7EE72ABF4,0x62AFCA4BCF30566E,0xA833AD30F865952E,0xB7971112E70364B6,0x5CAD8544E9A3F63F,0x4F5598797C05B460,0xAA0E6531CF80CAC0,0x3A755DBCAF445B66,0x64DE5CB0AAF8F98D,0x3E541811177AE632,0xFA52F0D9762DC4AE,0x62B86FB800773FC7,0x9980170DB56D9C39,0x550C844661E89E5E,0x30809054F1E23175,0xBF3AB9A4E8366C9D,0x0A24A557B62ACD98,0xD4AD1A8D62C994DF,0x000EDC1EF119455B,0x5F43519CC37A538A,0x678466EDA388AF08,0xF358B8F324C9ECB3,0x8DABF656F467FAB4,0xA2BB81A40D1D799E,0x01C359AFBE912021,0x92D283DA64DFDEB9,0x92915BED62A91F0B,0x37818FA0F41B5E1D,0x6BCC4EAE184812F8,0x26D415B0019AF317,0xF90D2B01989A17B8,0xE76ABDBB160C257F,0x77803CD5FCFCED11,0x1073CE9E1DAC8BC0,0xD66976C40F6CB8CF,0x87267F9DE750C862,0xCF5241233CD950A4,0xF963002A096BA857,0xDE396ED0D62A262B,0xE00651378C2D3DF5,0xDFA835FA6CF140EE,0x94EEE025EA517EF7,0x233EAC68FB841446,0xC5EB1EAC4B69964D,0x5859A50DC40A7456,0xFBA871C13515745F,0x4F6FA612C9C8BA77,0xB286A591A428BC5B,0xF827A1CAC3142A19,0x0292992672019BEA,0xA2BE31D63A5AA36E,0x4322AA76D5B0ABA5,0x36BAF44F803F7292,0xD531687BFFE28B51,0x09C9B492EF12D843,0xE0188DA7FFD2E2C1,0xE2E10F5E474E4879,0x6EAF7B23943F283F,0x8FE201AFEBA41FAD,0x4F6E1558F3E47991,0x4FEB3BEDAF0CC25A,0xC4D2AE39D3E2B2DF,0xE72810C0B258A2CE,0xA3507C12D3876E3A,0xE342149A6702A4D6,0xA0EC894DA2970799,0x86BF34D80D3C4453,0xD4485D48D4A7D84B,0x864B3D13556CC366,0x89A694C9512D2DAA,0xCC2A60C73C938008,0x55CB928EBB1D57AF,0xBFCEC7FF7CB22647,0xC968FA6E1AE9AF80,0xC05534AEE11DDB0C,0x27397698C982D282,0x2DEC90D511F36E2F,0x60804FDD3541CE35,0xCC35D5F42E6AA5F5,0xE3764464CE4A3937,0xC5734EB5BA2DBDEF,0x37ED146AEABE0154,0x68A8CF0B0873468C,0xB80B79B89B98D780,0xC7298BEA3822A982,0xF4998019B348B9DC,0x25F3465EA53F97FC,0x893CCDA3E9949706,0xBE9B5F6BACEB2077,0xF3380B90E466AAE4,0xF3B6B95705D433FB,0x89F793270FF11EB2,0xC68B01867B5B82B7,0xA02CA0049C0301DC,0xF3375F96666009DD,0x67D60C5AEFB6F087,0x8C64F7CBA45D4DB6,0x04D2CE330DB8D126,0x73E45FACF98A8BBC,0xDE3612B4B311DB40,0x812EAFE2526016A0,0xAD37DCDF45507271,0x465425E15BB5B6BD,0xC0F57F66CB39B6D3,0x99020E6F01864A8E,0xB9DC123AF3A34F18,0x1DA24575598289C2,0xCD390B41F652286E,0x3EECDD6E9EEB8BBE,0x210345CF84106370,0xA7B72FC4FAB69AB1,0x6AC3521752DAE9D2,0xFFA9761BC6FD8BFE,0x3923D78CD6CB829D,0x8D8244DF00D209AA,0x86A716AC1C5EACA3,0xEEC3C9578B0F22CE,0xE32D172DCCD52E9F,0x152A7075A4B2963A,0x18E87DED88157672,0x582A358C6D70C70E,0x438EAAC75CCC8177,0xB058A32BB4701E11,0xC23479FC27C66661,0xAA9B595C2AB7179D,0xBDC4177528C1F0D1,0x9B789348CF98D766,0xE0493277AA541135,0x09EF813AB0AE25FB,0x56648863311BAF23,0x11CF1772F732062A,0xF6D6C18AB3796FA7,0xCD636E6152E93A40,0xD0F6C31D3FB3D3E7,0x701ED863BFF4674B,0x7BA3D3E7B4D0238B,0x4516CE813E7C55D2,0xC4C99B63151D44A8,0xD8579834AC870574,0x0CA258E2B0166C2D,0xA9550BDD40DAA70C,0x07E92D41DC540A0C,0x78415DC8E1E68282,0xE39A3232B9B1CE71,0x06E2CC9972FB65D5,0x371F449DB39D9F2A,0x277B3A05C534DEB5,0x052A3DC7E277581B,0x8390B30F65377FB6,0x2088F6FEEA7F1A0E,0x494AEF9E292355C0,0x142D16CA7C5AFEC1,0xD10305E1A1958BE8,0x06C1D928AEF04065,0xA0A1749230DACCC5,0x9F5833CC6B221A0C,0x87C1F0D62A04438E,0xF5861C3724D9762B,0x93BB9FB21E20669B,0x9C6DA81C34564AAC,0xD53D53C0A5335C42,0xAB44BDFE704BD5AA,0x6A81C1FE6B33B90C,0xF755B55CE4B149E8,0x7FC4367236AE6A8E,0xF1D8186018CA77D6,0x2CA4462A75E6BCF5,0x705FF17E7BCE68D5,0x4BE4C4A4B08BE7B7,0x94E3AE5E3084949A,0xFFCDFA8C2919A257,0x78DDC38C02627001,0x5858381096C1512F,0x90651B4B00B318CB,0xE05C3BD63B5F1B62,0x533C783F7476BFFC,0xDC9CA558733D6379,0xF4F619FB07D80E71,0x515085862632D5EB,0xFFF1BEDB3198E89D,0xF0A54A43FBFCBDDB,0xAEBA37AEA22A39F9,0x4DE96EAAAA075231,0xF18E87F800F3D6E2,0xBF98DF710A392C5B,0xA32A97738625EDE4,0x2C4C34F4722C4C11,0x220E04ABA000FF76,0x71902FBD3E12626A,0x276DE29C8C9F5DFE,0xFAD644092509B0CD,0x3F1037903A5995BD,0x099D86AA66E06929,0x39D6C156858C892A,0xD635CCBFBFBD1664,0xF2207B83580A31EB,0x6922531DB0F784B4,0x1DEAA4E79D058997,0x8EEEE6CD31621326,0xC1C41A7D9C99CC03,0xCDDC7297025E08A2,0x2BDEC7DB92CB862C,0x97D1EEC3D62DDF31,0x59630EC00E7F0529,0xF1142D8CC506BA03,0x8DA54CE11A08A059,0xE1D917103DDA689D,0x0582EF21E6A85B3C,0x7AF2456AB0013A65,0x376B4FF71CF30618,0x82D64BE6EB08373B,0xB0254139C0B35AAB,0xF9A76287B1EBEEA4,0x6E61B0D685AA7396,0xDAA6996D841776AF,0x6807CF51AF001A62,0xFD70A25E801FA4C0,0x79BC40704FE655EC,0x52E551A6789ACB89,0x542B8F3D7408BF44,0x9598643798DC696A,0x1D218198032424B8,0x68D1D0799FCFED7C,0x28E32A7C33A5B972,0x11E330C064B568AA,0x21E03A29B4200C9D,0x2BDD6F37BFDBD31A,0x3BC56F676BF4995C,0xE961A31EF16138D3,0x042A4DDBE08EFB35,0x825BF09BCE60E702,0x414A8A2C78BBD8A9,0x7BB5D97A4434E0FD,0x0F5C140E73200C47,0x13C882265B619E72,0x4FAD4691C6FD1683,0xF4DD21FB94B3808B,0xB92374A095166A97,0xC2CD6725CC85857E,0x1FC0572C55269076,0xDF940A9F8905B2B8,0x822A5551DC4096A9,0x17FD756663C33FE1,0x5053EE7AA8EEA8EF,0xE2AFDA505D67DC56,0x0CB8256EE90F2DFA,0xD7B6A9CDA1F70F3C,0x75A3FD1C566BE091,0x4898321598B4DFC5,0xF4DF476CBED2BA87,0x200B66F209B75937,0x2D1B713164EDD8C6,0x176903910B961746,0x2E63B15834375EE3,0x1DBDB8D132C4CF66,0xEAC8966AE6C5D45A,0xB26D29F12D984987,0x7A0B54C5DFF1FDAC,0x7CE71E1B289F00BD,0x1DC1798DCAAC9266,0xC6139A1136665A9B,0x3E3DBE76EDA8F064,0xA2DF21D5EF1177B7,0xC9F38A2C112A3CCB,0x5B9E768A1DBEED45,0xF8ECA9233F681733,0x819725647EB59D39,0x295017F4E3A2F984,0xD6317AC237383DF7,0x838215A6DAD5B3AC,0x409410FA524E7322,0xE7E3E64C1E6159E3,0xF0E60E6CB33A0CC7,0xDF829F0EAECE3B3A,0x96B19770E969A13F,0x5DB73B7C50B5ABF0,0xC85E013BFEBF34E5,0x8A7DFB7F98D59F06,0x6F8F8051098968B4,0xBCF1092F9D61E6E7,0x344C85D6AE5A3C53,0xA42115C8E2121D4D,0xD1DAE45E269C3171,0x0960207F3D68FE5E,0x238BE9858ED56C05,0x4791098D9EFA7F42,0x8CA664762E52892B,0x62EB4299150E6F87,0x5476337861900366,0x69F897209CC23CD9,0xF8E13BE93A4BCD6E,0x5D2F27067259E3DD,0x747050D708F36AB5,0xBC5C075D072C1E43,0xD115463D7D8EECF6,0xBE8A8D230B4770A7,0x9D6F4510FA79B3E2,0xCF08DAF2CAC2F84A,0x151B3E407A3F0DEE,0x588FE8B855652290,0x77E2F4704FEA3BF6,0xC494C4C514DEB1F0,0xCD21B7E0B15E81BE,0xAB7298EEF841A9A0,0xDD6BF1B66E5F6A93,0x54AA02FBDDEABC16,0x341E1B468FC9C7FF,0x692601830B9947B3,0x55EC8CB92D05626C,0xB9EDF8017231D1B8,0x2D7F021FAF8306ED,0xD960D02B4E4DCD9E,0x146D43F2AD6DC843,0xD1CD329493ACDDE0,0xD7F7A007A06D6D56,0x7064B4B277AE5CA0,0x2B61C67905DD044E,0x0E6A563496CD27AC,0xDAA0F1D81FEB7C72,0x0BB3FE90C2596169,0xE3EEB598A49B790A,0x4B5E11D6544B680B,0xB5C0BD1733781B7D,0xA2DE1B30F85B0C58,0x8286AB8139A14F0C,0xD231437CB972C6D0,0xDD3B7A8A94447033,0x4D20F57830E19BF1,0x5E7B647048157775,0xCAC6A71A37DEA3BC,0x309A9A00ABE27D42,0x61CB5B731EAFD127,0x2A91B92642F8BF14,0xEAD1215C9CAD5D88,0xC24964CB5F942282,0x792F836AC89DFBA2,0x9F7FBA7E783D1B90,0xF5C4A96B0DC2E85A,0xAAB850A66EB12861,0xE8519600338C80AA,0xD7D5F43CA6423433,0x0EA4177100BAE432,0x69355EE49AED7896,0x3386C63016081956,0x32C38420173806FC,0x5192B9BC2532AC8D,0x2EE0572D54F6DD25,0xBC594B1F8F5D198D,0x3D0E022B36CAB8B7,0x05EDB6134E276D63,0x8DBC8C62E4FBFE7B,0xCCB3C235A8410CA0,0x7549CD61C4CE29C7,0x7AE4EF34A0F318B4,0x50E53D7779FE407A,0x91D6E07A34F9EC79,0x65C24AD7D7434F1A,0xC885EDCA1CED1822,0x4892A5598210B7D1,0x5029427671110B9F,0x1FD286EF9C063A0D,0x1CA54D5079756F06,0x4417E2707D034BD0,0x7D23FEC139E92204,0x8A44B24631D07EA2,0x782848103C69FDD2,0x96DDB23F65C75D12,0x99F96964B4156373,0x945EE8F3BD57A01A,0x71236DB9CBDB2AA8,0x55984AF0F5D1456D,0xA317DD0FD8546EE5,0xAF0722BB0C69A025,0x49E70BDD3FA44858,0x19665FE2E7123EB5,0xF5DD38C40A2BC429,0x50C5AA9D4F31D7B9,0xDF5A26A34A4AE8D5,0xF7096321A02623D6,0x441B1723D99A1B04,0xF7B418CBC3589427,0x491973D3AD798EC5,0x6F2FFCA5A8163A6A,0xB9A250A3D8A231B2,0xAC667E7EA16CE810,0xEFFCA4A817909328,0x3B6744C4C0F5FBF4,0x8AE897407574255F,0xEC80D0CADB20CD49,0xA57572497EF9079D,0xA9792D626B7282F0,0x8345126F6CC694B5,0x9FC9C9BF92129730,0xE33E6D478C3A09B9,0x3B0CB706A18DF960,0x0A6EFFA88E8387B8,0xC3D9A6A2550A4D3B,0xA5C2201027A7F208,0xD787CA1E37BB226A,0x0AE546789577BBE6,0x5F5CC43559662351,0x845B44CA70C8DD82,0xEE990F06555E2093,0x003CD58E3678A853,0xEF0BAB517347CAED,0xFDC199C2D569933B,0xDA64CA8732D47E4D,0x4DE31BDF767F45E1,0x4B0BD90EB1CD9EAA,0xACD43E653BF2971B,0x6405973A63E55E89,0x997A42982D3EB3A0,0x02EFD3A43BF38766,0x01E77FE2A61FA1EC,0xEB775EF5220FFB31,0xD22AF5917556F699,0x0E901C1DFC43EA4C,0xC5FD581A0CAF4004,0x1AD08A2C56D6B67D,0xC4D6320E8926333E,0x12D3822350382C67,0x575750C25612B24E,0x854746D71F30E1EA,0x55F32421D81226B1,0x9E541E74A645BD72,0xF4B3FB368C6280F3,0x2F8053467A511ED0,0x6D27374BF77F1BC1,0xC44DD0A4A6811482,0x4E5D4330D1AC8C02,0xF24CCEFA6FBA90AE,0x6DD8ED906F744F18,0x2DCB766332BD708E,0x4F9D7781F30ECC30,0xEEA96336E9E7BD60,0xDB2F696737AA7DB0,0x155E08F5E1657544,0x9D0C40557A4C3CEE,0xB3596DBC35DE713C,0xD50AB821A7FFD7D6,0x45BCCEE9C8E7AF85,0x7941D5669B49772C,0x72CC83587127201D,0x917151261EC2DA32,0xAED95CA9E4A858C1,0xADDFFB06D2FB97DB,0x8FC6E5BC3601D489,0xD95FE9EBBA648E6C,0x25C45D14C497401E,0xA185C9C8FB03AA88,0x3A9AECA4F84CF336,0x16DC7D7EB14E8F8F,0x1E1F1C9EC373E476,0x3828F2AB89167811,0xF7C831B4AFD6563E,0x0EAAE8CFEFFE62F9,0xA10ABC52E5DC1071,0xD832E2D7E9650890,0x316C72F1F83B7296,0xA5B06BF114D14489,0x5D89190D819776C3,0x37F4D576AF5CE4C2,0x6A467D37512EE96F,0xE9BC110BB30B4378,0xE5E80047853B3332,0x6156CE98B04653BC,0xBCAC284541DF115C,0x82537A64D3D757F4,0xDBB4BCF516BE0CB2,0x8B220667274F46A2,0x5288DB9ADB9E64DC,0x2A164829C5AB3293,0x3B659CCE81D4830A,0xDB1E00DA53755EA9,0x1A6DCD4D4494BC2B,0x5598D871547A3E5F,0x99E1EEB9A345344E,0xF3BD25B7957CA823,0x330FAB5968308A06,0xEBE9609EAEDAAA52,0x51B2FF7E8B3E1E79,0x0308BC7914A39536,0xA2D193D173573685,0x7D309CA2D213E278,0x4C9F9F212CD757D2,0x38830480C243F862,0x85580023FEF6B201,0x77CF1260610D3036,0xC56644ADAF5D6042,0x0262BC34AC01608F,0xCA912E28E0E9F664,0x0B5712542D20AB99,0xCE15766B48BF6588,0xE0B32C9373BA06A6,0xF851F67E2A1D9735,0x6B6469DBBA1EDE15,0xA1BD5A26CEC7A52A,0x0751FC37CAC558F4,0xABF46E1E90244B4A,0x8569826375F758B5,0xD84E5AAD3BE8517E,0xD1B0453BED4AD935,0x1513B79F9D3BFF36,0x3FD1A6D1CD0EFC96,0xB4D8F89A4B7F51B8,0xFB8B3691FDA113A3,0xDDF197F300317465,0x81BB2200FBDAF3B8,0xCC848524829437CF,0x34C240562815FD4A,0x1098B873913B98BA,0x8EBA5DF4EA9B4157,0x7CE65D9E87BF12E5,0x78BFF4871B6669BD,0xE3E6438F348D30C1,0xB58D8B4B84AD049B,0x7086BD77D0D40695,0xBCA663A17ACFABF8,0xF4C6D129091A84B1,0xF7AE51A1F4924C3F,0x6C2148676A0B5473,0x6B76C749900D9CBD,0x300F7DA9609FB140,0x3A09647445983A42,0x6348813E4A682303,0xF1DE0F465F625017,0xD9B93D9CE47AC0E2,0xE84D5A622296E4D6,0xE68EDB0912260341,0x9B70A9B040FE03B1,0xE918166E4732510F,0x8151DFC5CF207BA2,0xD580EC8DA6ADB54B,0x5CC18C47F497EB90,0xBF75474CA0A674E9,0xA0C0AAF50B9C2EDD,0x9D739C5A90A6BE50,0x154CE8C9A244695C,0x2E34ED3E193F4018,0x7C98441405D31071,0x87EA8CD189A4381F,0xA256DCD5EA095037,0x70DF3C9048B3838F,0x33B2AB53FF4FC291,0x362913E4BCC2C8A6,0x3DFF2AE80F5DF334,0xD5DCBFF355957DB3,0xCC2D4EEC54699C39,0x4E7E877939076706,0x24B967BB231EC3D7,0xDF92078C35840067,0x7CD0FB398DDEFB43,0x6698874F1C6A3943,0x0555BDEDD4002A88,0x2F1BBE1B67994A6F,0x1123170C128F0A08,0x491C3F76E4E0611D,0x5D0926F6EC1C72D7,0x77CA369C547B68A2,0x023D0761750FA33C,0x2ACFD459A7B5B21D,0xF71528A8A1F1F5E4,0xD6C4BB2B68A21576,0xE906464E1646FD9D,0xAFA9B62D48BF5DEA,0x06E38013D8245330,0x0F4EBAE8EED239D4,0x5AAD432CFC225957,0xB8EC7319BAF4B5AA,0x49A5BEC862AA89C4,0x8486DCBEBE4BAAEB,0xFAE36E493AB7FD93,0xCFA027CC583FD134,0x1A1F0BADE29800F1,0xE942BA6220A325A0,0x8A2AD74796DAC7E1,0xBACAC669AD7CAFCE,0xABBFCE4EADE8F6E7,0x4080B46C0094A41F,0xE102852BEDBCE415,0xF73B750D2A709AB7,0xC208C474895499D5,0xF75DDE2D54848A42,0xE100994DE791793F,0xFEB99E326928F46A,0x1F816EF68E88CD00,0x6425A7525B5E0066,0xFA586BB31FA54521,0x39B7CD9A33563CD8,0x6165C71AEDDB6479,0x5B8412496FA14BAB,0xF3484682BDE51D61,0x1604DA1B84891C22,0xEA77A15854F1768D,0x54A4BC0612454CBD,0x12A732DB8895E3A9,0xB244C462FA2E930C,0x1043CC7195338CFA,0x9E75177FF4D47A91,0x953ADF1EFEDA5C5D,0xBE5BBA342FB23216,0xDAD6249A210981AA,0x6DE26F0765E76D21,0x3A31B68E55DA38AF,0xDBDDF4BC4F26E38E,0x19C6DFBB0EECA462,0x319D1D06DD5B2071,0xB9B2C142871910AC,0x4940A506FC85D103,0x1228B3C328D7A6E0,0x8A7584886001C0E5,0x95F2817D2802B2CC,0x7830AA7B4FDC6ED0,0x5EB13A07B55895A5,0xE52E6548FA6BAABA,0xD99D6AE1A2090794,0x790CDF57BFFA7228,0x79A0367B6B5D447C,0xFF99691BED3E5B08,0x3EE0E0C24AB806A0,0x219031036D607FD1,0x7F6EEFF51AB1224B,0x1CB3ACBC8DD3CD0E,0xBAB954B1F5190CD1,0x322593C8DBC778B8,0xDD53D0775668EC42,0x1DDD834C2A37DD6B,0xBB12B050CB43E9E4,0x4647593BB713A686,0x5FC47F1D3DA06CCC,0x6F263F224394A3FB,0xBA39BC9CF574D75F,0xC8AA130D44DE5D0D,0xB78D035B9D10240A,0x7325A74791B71BA6,0xBC8A6F52F1016BC4,0xAD221E045D0E40DB,0xA3EDDA7CC6D8671B,0x08208E6BDAFD2E95,0x7781E99DEFB97786,0x5E639F5AA0F37F75,0xF7D3B9A8B9F4036E,0xC2CB4E09007D9ABB,0x931FD0CFB2F09A98,0x30C6798BAC9A700E,0x3FA91D7FEA4C3434,0xCFA9D9CD7CC39E3C,0x81BB4C5BD5F410C3,0xF706F17773E22CBE,0xF4DF138A4C57A412,0xDBD792DAC676AD03,0x4CCF1852745935FA,0x4480B7FCB989A4D9,0x7A4538E00A852339,0x19F65A8C4F83EC0F,0x2E12B90FFE94EAD8,0x8C5DB5C27E552801,0x989FC5A9255C51ED,0xA3B6766DD1DC9764,0x47F4527DF2D6F068,0x7BD121CD19DF3200,0x74071404E61E613C,0x7D1A4E3EC4B36999,0xBE0368C67B1E1429,0xDFE658E3271ECB3B,0x9566D8DCE4552F11,0x6A81B9160D338E25,0x5F3ABCF82AE59B95,0x686D4109C413AFE9,0x099FDD36A87E73BD,0x8AC713C43CD131A4,0xE577B65963B89E33,0xB8940428E3D025D2,0x61715CE2E79F2AD7,0x310C0D1B6D036BF3,0xDEA6170A89B396A5,0x97AEFFA924E77F62,0x47113C8D5EAA9074,0x652D256C5A039697,0x95E495031C0E9E00,0xDCE92CF942D56807,0xD796464178BC1DAA,0x9461F7A3694AC4B2,0x76AC01A204C15069,0x2D56F2F2CEFF8BD8,0xFD967F8382A382CC,0x58EDF5906DE5B001,0x8E13044FE6A0D6CD,0x9F778925A28CCD23,0xF99647044401F0A9,0xAB17A94CCF718B1E,0xBD6FC232204A792E,0xC0FCF02679F5DE37,0x7783A58C6289D6AF,0x7D580938B2A98BBF,0x5294A153B26B20EE,0x4F1ADCCFF1C297F5,0x668E52FBBB345A9E,0x8EB42713E4F016E5,0x0D6B3C28E56B71FB,0xD25A85289A3E54F8,0x461493A1AADBBEBA,0xF135BE1DAA890EFE,0x12714CB57EEA4C65,0xAE27AB19C0F21C8A,0x3F427C3E65954F4A,0x118C1008BCEC786D,0x4BADE4285DF781A5,0x77C25956F7BC6ECF,0x34F09C8D8EA5393C,0x5245E3D531BBD886,0xD3D7D144D682E5B4,0xE341FE56130E9417,0x7FD68B76E93502B2,0xEC14FC935CE51E62,0x94211E1F58FFDEDD,0xC89F24DFC71C4100,0xC25216B44B663BD4,0xC31B6482A0FC6C2C,0x8B141DCFF6910E37,0xD175A167D403A986,0x8EA531A4EF456EE5,0x5AACCB70F2DEEC19,0x47C3E2AD0C2E5D0C,0xCF12658EB82A18A9,0xCC39452A2FBB0713,0xA449A3632ECF665F,0xB9DE9C4D4F715022,0x32D1626A8666BDE8,0xD832C306A705FDF4,0xFC79F52E4B9F0376,0x76DECCD4B70B523E,0xBB4336A8C37FDE31,0xB938E48F2E88373B,0x34A363C2E85C6A2B,0x07F3382F0B51E62E,0xA7D537E9AF56F379,0x5A82ED60DBD48D68,0x129BFD9790DE55D4,0x0B24B711858DA3C4,0xA99B0420F30B33C9,0xFDAFE70F681FB315,0x139B4AB03D8B63BF,0xA166A7771C9A0871,0x0CD0DAC7F44D9F46,0x6F8925DC9013F2D6,0xB9A59D35358275AD,0xC50DBE7D537F5242,0xE5D35E3669DB1503,0xF99CC2DCE6F485AD,0x7C49C1C8D6430B6B,0x3A7D88141B5A5904,0x04FCCB99BAD318C4,0x8AC90CB5F41CFA66,0x81636C6B67A0999B,0x4E17D300B514921F,0x3ACA8656DDD1BC7F,0x6B41990AB18D21CE,0x3DA850C86DF9ACE6,0x8C359A40EA86A0B1,0xE34900FFAC9ADB86,0x69B68B120AE154C8,0xFD77BA359D49626B,0xF05C1E63A9F2DA51,0x480D93664F61921E,0x4D082B8D86491C33,0x76C677830324F183,0x2046563D3C72E29C,0x3328F5EA29D12509,0x6109C74B713B7B9E,0xD1DD578BE4B4B3EA,0x9EFF9C8903975C90,0xAD635B09A1097511,0x23D7705350AA0008,0xB97F5060E83DC235,0xD4FCF4BF683F9759,0x8A15EF38059A007C,0x98F35FAA72BEB366,0x0F864343A3A8DEE6,0xAE46B671BB11A2E0,0x4C68E114DF1A78E7,0x3B7E57D7469D57D8,0xC38267D57C8BC1A0,0xADD3F2D0917B593B,0xB61408CD17EA28CD,0x5F3891A1647765B4,0x9F220C2D7CD73DA0,0xB9A3EBEA84B202CE,0xC7450D52EAC5DC63,0xB851DADE066B4392,0x7C5975BE12E32B57,0x2E76A364947FBC8C,0xB70020F88E445D3D,0x95EA1B61B96BE96D,0xEF3322DC5EE482A8,0x630CE88A7279AD9C,0x7675836C72306097,0x6A209B50D6F16169,0x0E674F22991A916C,0x16B1520D0A12DB87,0x12FC762415C01DAC,0x22A75B75D6100074,0xED9841C8CBB75F00,0x3529D1D961E58DE6,0x22212CD1A2FCD3F7,0xC07763255B614F3C,0x8174385C7CAE8733,0xE0CA960187720C11,0x183F591A0E650924,0x30F539BFAFC075F8,0xEC6F0DB3FC913AB5,0x232081D57E2BF6CD,0x6A2C0F4412F0E510,0x76EEF2C5C3AFE790,0xB5877FF3E022E5E9,0x0E8235865F0DFBEC,0x97E316F9C8AFD95E,0x7C774E73A35CAD0A,0x17CE393E53969A6E,0xA4017FE2ACA7E254,0xE4C580B89FD1A6B5,0x7DC6F3A33026CEA7,0x79DF01317F3866C5,0x0183AD859D853235,0x9CD7AC6731188A75,0xEB3A44FA25B5AD4E,0xD1CE9FD4466BE5DF,0xB7DAE91D04936558,0x57ED665DE06A45E2,0x64344985261E6697,0x126B0E7706C82538,0x108A1A857FA3A86F,0xAD08552F643129B9,0xE0DD4CEF23855F4B,0x87ACCE57C9D6F591,0xE01593EB6D5F28F2,0x35217B0DB8495DED,0x09F208E0DB269648,0x33A522FB77E3EE72,0xCE3255FD093368FE,0x98D049E22E2072F9,0x68B2AA15EF2F0772,0xB1ABC995DB5EE2F6,0x588C3BFE26F86425,0x575C82D08EE037BF,0x7DD548563AD3F858,0xE81C9A5D44C3F8BF,0x69A749BACE012C78,0x57C805DC2E595DD5,0xDD501D73FA019983,0xB8C157B9DCA7112B,0x50A1B6266DC13462,0x570B0FFEA1C84A06,0x0445D69A1BB2351A,0x111991F6202D8A94,0x02C8C0A8A3E61874,0xB4E821E74BB252A5,0xCCDE44D55F989FD9,0x05D6114F1511C1D1,0x08B0133955BFFF4E,0x081440C9F0F6DAE0,0x7647504D4AF8FF20,0xC741C9F6A020AC31,0xAE952520CED4DBC3,0xB59687D1CA82D107,0x5B72651BDFCB1A20,0x241BEAD4C30B49FF,0xCD4DA15713610ED3,0x155037710B4360AB,0xE74D2E9654E6BCF7,0x60DD04429A23370C,0x3AC8685A0E3C0034,0x5A38BACCE778DAB3,0x8FDA80DE3431CE3A,0x471289138769F31D,0x980DFB5B988D1A4C,0xFFFA7C23417DA152,0xF7454FFFBFAE5A96,0x1438119FEFA475E2,0xB3A9F1E10AFC2FE3,0x31CF330F3B23F7DB,0xEBED634DD240DE27,0xB8DF2EA5DBBAC675,0x358D20CBB3A5B96F,0x26693397AB54651E,0x968150038FEBAD2D,0x25E07E9F77F10CA4,0xCE928E1F24E94759,0xEA6C2CE7265AABA6,0x4FBB87BB290C98E5,0xD92A793A12299E19,0x70EAAFCFCBE758F3,0xC1D07D142D42A1EC,0xE118B4F540FF1955,0x6C7EDDE5E9DBA580,0xCE70E2B1465C882E,0x26E8958C5D536F21,0x07E42DAF2FC09216,0x60D8CE9C826BB842,0xEA6ED4FC8AB10678,0xF2CAAF3D5ED131A3,0xCC2E9737CE503C94,0x09544336DCCA1662,0xD288C510D538DCB5,0x05EFC5713DDD876C,0xBA9A7D83C082D41F,0x2177E5DB36D864C5,0x48B6F8373F9929C1,0xEF10E66A1C6A4FC9,0x79EBA10CF0C57F7D,0x9B70DD8C3D82DC10,0x09E2ABFA86CA0E1E,0x5843B36D3DC94082,0x0A232BCC2F50FAD6,0x0D0F06207B4C0BD9,0xAEB35EE8C16A7020,0xDDE37650AF681710,0xCAC9A8E8982371F0,0xDFA2B4524F9A1A1F,0x23B0E42EEA8A44B0,0xC1BAD11A380F297A,0xFACBD29236AEE086,0x3F9F74215BF3BCD5,0x36D7CE9382F84B16,0x9E6877386CAC5241,0xA61254BBB68BD75F,0x88BC7BBF36E3D2A5,0x42A4AD7D4814D01A,0x6018D54503E2378D,0x93F5D9D5583E0067,0xE82AC716F82A05D6,0x38A8C5EE3E099603,0xC92C492EA342B6BF,0xD753D10FAB8B037A,0xEBB240AE17E0A752,0x5D80B75E021B6207,0x6E127DEDA1360144,0x025FCA09318F4184,0xE5049791C3DA45BF,0x24ACCC0C651C7BE8,0x697E34F28C4CAAA7,0x67BC3A27B7AEAF5B,0x13BF7C20C98B9735,0x8BC1CA76E105E9E5,0x5C872EC0E4C9598B,0x5F7E65F948FD34AD,0xC0E3269BFE253241,0x4E00DFABB75D7FC9,0x707240D4149ACB36,0xC2E2D287B6CAC086,0x5A3D850A2E721B0C,0x7A39BB2078132699,0x98BD33809C5A680A,0xFD7D8CBD8C8474CE,0x564131D0EF54061C,0x9CE602822A4BD786,0xC8398A3218BFBC37,0x1748896A826DEE96,0xD25BFA7BEA3ACABF,0xF8624E6877A3026B,0x38BDEA678519D6F2,0x7623F61874D7666A,0xB8B81D6231E75CA7,0x02C979AA8C0001DE,0xDF6E4D5AF0BBC0F4,0xBD8FB866A4142246,0xD83D220D86D963F9,0xA176296D2364186D,0x4417CF615459EA99,0xBB4A15F04D19DBC3,0xDFDEB9D6B1E53B72,0x32B5D2080D5A0D31,0xB35AD31CC3E7352D,0x39557631D9D0AAF8,0xD1F21D0CC638CC68,0xD1A61C91AB97D0DC,0xD0A80F39B82F68C9,0xA097C9E2377E4979,0x072F66F2FA202FDF,0xCCB83EA0CDBB9751,0x191AE929B5AB3E47,0x8483BA3E78A7D2D7,0x1B45AC51F1C40C77,0x7F7683E8BF3FD2CA,0xCDE719D10EBEB1B6,0x28536BD49A55C4D6,0x079C6B94DBD2AE4F,0xF6CC94AC1F62D72E,0xC75AF0B68B26779B,0x2CD61F7D93E3FF08,0x74F80174597F66B8,0xF393F0A979DE1B37,0x0C9E03CBCA0F18AE,0x3F36DBCAAA13E6D9,0xEC9C404460B8A112,0x406D1499D3D0A196,0xDC8B36F6F2720075,0xB0BF8B19289BE773,0x45F080E89762957F,0x4B309F2990122AB6,0x252A046642A285E0,0xE6879DEB694F138A,0xB5707B8D91866F4E,0x96E4EB9F9D462671,0x4461A51CC5C26F46,0x28E45FC0E71225E5,0x2259DA83EF54EBBD,0x33645E90DB9DCE64,0x5A13897D40583BB1,0xE07652D5C5AB2D79,0x762BABDD13821162,0x0C55018F1A259D10,0x7AD3B0FC0EE82E01,0x82F912D9DE0DAF05,0x4DDF98D373BECB0E,0xF979C0EB22848418,0x2D7C7DCA947304FA,0xD1D97AB6AEDC56DB,0x86CDCEA49A3D3BFF,0xDAB58750846EE03C,0x27B9E10608C0E73B,0x4AAFF8A431CC8546,0x6EA7010E17F6FF00,0x624C777E1BC5F0B3,0x80C0C18DCF16B993,0x67FD9E8109C0B4B6,0xCD1CBD0EE957B44E,0xD5A94C0B24030572,0xD47712CDF36BB52D,0x40ADAAE5B0826D37,0x0834B4D31DE77DC0,0x6F7A7582354C7A25,0x336083F54C5F8D9F,0x0873C5EF32B76FA1,0xEE0F469B8B6DDCF5,0x8FB011E81EDEDF02,0xC7DD43A0C43EBDFD,0x189E86A01B621399,0x001A6F1E2B45EEAA,0xC654E4EB0FAFB306,0x55A090759488A415,0xB4186BF2BB77D64B,0xF207D02F4DB89A13,0x4FA8BDDDB1643BD0,0xF25436A684F5BFE8,0x2F40EF26251F6A78,0x86D83F97F06B8D00,0x052701BFFF83E7A2,0x1F9177A33F4E5F8E,0x138801A2035D5251,0xD1A380325428980B,0xE9B5E3D29A15E3E1,0x7D9D3B6DE9A223BF,0xDCE7701CD1591F93,0x3AB4B45E02402041,0x0A5978B453B9C612,0xEBEB8B86428F394E,0x5DE4371A39565364,0x203B096124F15665,0xAE9227FB7E267380,0xCC9A8E0AF9468A69,0xFF686DE0863CB669,0x986766FAF04EC1F3,0xB734B05DD0A21CC1,0x8BA340E7F150DE8A,0xC1D68EDAD08C3EB2,0x9568253B68C87DB4,0x7555E301666308F1,0x812ED27250746F0C,0x571761E0CDD17717,0xC631AA3B714FD3C9,0xCCFD3C26368D10C0,0xFFF2926B0CDEB415,0x52D73F57A06C8D87,0xBABB18185E4FBCA5,0x920EBB12D5420AA6,0x226B43024164349A,0xEBE2FE8B4A505F97,0x0112620AD9DF9D92,0x9B483E6B7549E416,0xBF5FB86196540921,0xEA00F0561F0D5734,0x1B7BF27F66796574,0x6055A582D2B29473,0x62857CDAA105745A,0x6214FC205AA95CC4,0x49CE21FE7EEA97B1,0x1A472A711019E99A,0x4427C9F346070ECA,0x0ABF452625AA3F88,0x8703D59732C0A408,0xD9CFB912DF91487F,0x2A1DD3621C863A34,0x3E07302DD5DC70ED,0x6423CD56DAB12E51,0x71F3D92BD26D914E,0xAC14E01BF9CC981C,0x4612D77757613C80,0xEE78E2E16AE9A8ED,0x59EAABA423A88D3A,0xF5D01003985EDD9F,0x40C5E6202C4CE9DF,0xA884CC3A291DCEA9,0x7658D03DD10A5F03,0xCCB05585FCCAF958,0xF66F2BA208219B72,0x73512BF3655F5EA0,0xEBC2782D62BAB31E,0xA9BDD49D2F6714A8,0xA3676A2664FE8F4D,0xFBB052ABA3395FD2,0x64F417D650585F8E,0x7C14FB746B4680EE,0x74011C8DB27BF4BD,0x8CA5FFA157266744,0x4A8A987CF03D0D9C,0x64A2D741CB837B09,0x64741976609F0C04,0xD0E72CC7CB3B785F,0x370695C369D0E2A2,0xFB4580713017F38E,0x8DC9AC58E4A1F5AD,0x06E8F24BB975D105,0x5F1975CF6D39FF78,0xDB228633BEAE18D8,0x8DF455887D088749,0xC4EF0F56B2C3F769,0x019F7983D9EE7694,0x956605796EAF8994,0x8E46F04BB358829C,0xF13CC5AC0565AE90,0x82D7443C24A72CF4,0x27D5CDD124B92930,0x40106220DEDD1D98,0x6E4ADF5A7C66BBAB,0xE4B45361DCB2288D,0x119F7FA355C0BFFC,0xFEC0247249B03858,0xF890D613AECA39F3,0xE7D420E1181F9129,0x33080AC60963D3E7,0x5EAA548267D8D236,0x32030CF0977C1451,0x08CB0AFD90B819B8,0x4A2EEB55A9DEC9E6,0x3E23AFDE737FF4CC,0xB97FA24BDB355AF2,0xF4D511ECCA7E24A7,0x81979E205EFD736D,0x81380DF78FA3310D,0xC09B052F11D599D9,0xC800A53D66E2C38F,0x35774EDF70E03D41,0x4979EC8014A6E2E7,0xB5BB6319346CB6E8,0x9D04EEC64267CF9E,0xAE2AD04549B6327C,0x7516F440EB1D1069,0xFF0A32E18960A558,0x9DA533D430F6025D,0xD0FCE8D2E4611876,0x4BDB1419C5CB062F,0xD62B21A3EBD42BB1,0x55BF01C8BB07C54D,0xA84FB2A655DCD1CD,0xE470982E74A0FB73,0xBC193945C89579F7,0xF35B727E3638C839,0x44B7E0D2C02BDD9D,0xF1251FA308EF1C08,0x2C64C19DC85D3CD3,0x84B866FE9BD322F5,0x7DB4EFD04938EFA3,0x5B78B6D0E39748B1,0xEF47D0E0E9346323,0x321A6B372B38C835,0x17BEF9DA8877B3BC,0xFEF01ED20698E0CE,0xBAB5EFF0F133B5EF,0x8AD114E730C9FA8A,0x8AAC2C52FEC59C9E,0xC04847B74207000B,0xEE1C1745DE9D1B9E,0x96336445DD8831A8,0x467AFC2F39748F35,0x25BC6BC6ED0BC3F8,0x6EEE8C82E31CE804,0x4EC4FC8EF4EC1658,0x78CBE619837E0717,0xEC7843D903E9A1A3,0x18EC4BA8558F0423,0x43A09DCEF686FAD1,0xE85CB60F4E244F56,0xC08069CC7F474072,0x55B697612114AC2F,0xCAA647575D3F0051,0x52A48048CF340A24,0x7D81B34FF948D903,0x04712B8CCC6D0B7C,0x726DDD8760445570,0x0E299DFEB6E640A8,0x5E79EDDF4FBFFDE0,0x745ABC40FF3ACE64,0xB234BB457B64C9E8,0xBAA7C22BB62AF1C7,0x9229A532002EF988,0x34118ED347071B57,0x679ECDF98DFE333B,0xAC0C49FCC59BF4CB,0x0E32237A5F8D7AEC,0x130BE50A95CC19C6,0x59374A077F59C09C,0xB0154D386841EA1C,0xE0AABD46D54692D8,0x59AF40EE0E8C2F93,0xADE393B9CB1FF84A,0xA8DFB9634F321907,0x6FB4A8EA759A92C5,0x55190E996EE29275,0xF41857FCB9629677,0x08E3D289683A61C9,0x1906BBB038F0DD4E,0x658CBD4AB9E5F187,0x1788AFBD9A0F82FF,0x1DFDFCE295A93D3D,0x3349252E28D4317C,0x49CAC115EDA78029,0xCFFED1A00928A989,0x3845ECA9C546F47B,0x016F4E4807D216D5,0x1E52F1E3A4CF1B84,0x4D594178BB135319,0xFF285F6AA405D1F4,0x86A69A507E59996D,0x2D9E8BEDB3F2AD0F,0xF0C8F69938A4B3D9,0x8FD87AFD5F169811,0x09352E88F04B1F47,0x0C901F8E906A7A8D,0x167CE9FA06105B99,0xEE659CDFBF859755,0x57149EE2A0716974,0x864CE8BD7235EB70,0x9E43BD8FAFC33954,0x9E67D88291C2DD27,0x482BC978899345C4,0x778B69F658D9F23B,0x0A658B1CE165F9D5,0xC832CE6A4DB20BDB,0x7EFE9FF81D578239,0x827915170651E67D,0x03654B7ADCFCC8B6,0xD1FA1D4C640A6B26,0x6C1331F51E9CBEE4,0xA20E9B54A1A05119,0xB8C6D1D5920498D7,0x1A91B962377E18FE,0xA25CB80677A24AD0,0xF8C0E4BEB017FF0B,0x8DDB768FE1772C05,0x493BC5375E3CDD1F,0x0D98004B06E6BC71,0x9DC047A1213F76CD,0x8358596450175A19,0x635D1F8E77CF2E99,0xE5A36102BD7CCC1F,0xFCEBDB30F6FB94AC,0x2E0B89CAF74A4E22,0x59181D7768CA9D90,0xC787C6A2A2AD2F98,0x41B0B2446363C128,0x08E0162B119B97E4,0x3DF2CC34B03B0D05,0xFDF617167FB33607,0x9A78DFBD1CB7D7EB,0x8377ABD77AFBC058,0x088FC133155BC5F0,0xD438BB5CF3F1766E,0x21E4AE09E5EE4E75,0xAC12380458EA5F91,0x2E4CF53BB9191098,0xFF7F9BC0F7EB1B81,0x42DCC9F0B1B3CC8E,0xFA31BA8931757511,0xDD25C10FB1462AD1,0x6CBE893D6B3096D2,0x3B0E6880EDE74575,0x27C4BD0A6039D77C,0xC8479FD86D6E139A,0x97B1B2B87E096EB2,0x562EF7F48CEC9AC4,0x03521D1647969117,0x75AD7D1744E621EC,0x07617331CB98AEEA,0xA6EC9849106E2FF9,0x851BB2D0E465C460,0xB2C75CBF4E8CD378,0x38144516D236CDBF,0xB3411F074DF94AC5,0xF013390DEFC6323C,0x195BD9AB88C2D466,0x1A88B0B6A69BD4C0,0xE747703B2A59AF7F,0x29D6C6EE7D6BE457,0xEBEEA0BD0910BF12,0xD37222A87250D6A1,0x96400EC17ADD7A15,0x31F5BF6C8AA29418,0x31182D9DCECF025E,0xF3DAD013397543DD,0xA11F39965E5DA7E0,0xB7A43A4AEE94B140,0x10CF961F5480765C,0x9719B41EBD0588F6,0xD79D95616DDE6DCA,0x31B0737E59001176,0x9706A1182A8386AB,0xD8A73B0C8F61899B,0xDEB51C4CB0145C08,0xC4FE94697B42D7B7,0xFFD1C1C71EED951B,0x136DBEA19F354876,0x048E03283A6F3053,0x3903A60C352F5236,0xB982C3C1317D4BC7,0xB95A5BFD5CE4481B,0x835E94FC0D672365,0xF59E0595498F63A8,0xF95A8F85BE49B43C,0x8197E06140FDDF5B,0x3D92F3B504512ACD,0x1580659C52CD37AA,0xE3F5DE170F0F0AB9,0x8D3B1F29B36148D9,0x5816EAFEB0529ABB,0x419B05EFE2F28F5E,0x3B683885EC23FAEC,0x574640028D2FDB9C,0x3630658B74DFDB23,0xFDEDC672354DC495,0xD2C6D937069A4564,0x4AA1D8DE3270B815,0x9D5E80FEED4EF671,0x3B3D157F7C7AC253,0x8C26D6B72C831970,0xC659B852C2C65904,0x78804498B1169A88,0xF436A36E4424CDA4,0x7F595AE97D877FC3,0xB8F6ED3688A57E0E,0xD0A4978F5F36FB5F,0xD76A733E0FE29C35,0xF81625FA1D3FFF46,0x5D06EDF6BCB9EB47,0xA813E9A2A31796C3,0xE80C297D23CC80A0,0x3CDAA31BD2AC91DA,0x6ED9751FE1B5139A,0x6B765FA9E80584E8,0xB25F689A6208D93F,0xBE01A762F7013671,0xAA1E545E12BA175B,0xE5CE0493985DC8D2,0xC16AE2ECC3829186,0x7B7B03704B664775,0xBD521BCE3EDA1D77,0xE8FED1FB776109BA,0x87C81024E5A6CC35,0x345D6B04EC159111,0x82382E43029F837E,0x24B2BC57963380E1,0x05194A7AD23D48A1,0x0EE2346A50C2DE95,0x5672897C2856E818,0x0FE0B1B6D1FAD3BF,0x5130709F8CB9D8AC,0xC889E360F0536AB8,0x58E6C55D90798CF0,0x21355033D3C290E3,0xAFC245CDB65CB2A8,0x472ED20D9FE81631,0xA6BD49221942A81B,0xA7B523598A3F3DC7,0x3E203B5FC240399B,0x04EAA3CB3921687D,0x0DCDA07E4CA35F59,0xD0E3A225F253FEFE,0x0869E585A4FE8BCC,0x0691D5773E664974,0x558CFAF85B1EEDDF,0x35B124970E82E9CC,0xFD16C8074E2EC521,0xEDCFB7F52415E382,0xDDBF72678A56CCFC,0x56265C2193318158,0x0E1FEA32BCD65CED,0xBB8C096819BA6782,0x5DE87D9E445D2755,0xFFD3C2C98E13341F,0xA02B7261F89D0BE5,0xC3FE7120696CFBE4,0xEE8F543606054F23,0xF18DD4D6DE45ACD4,0x4563176E58791159,0x984049D1FE90971D,0x53C9B53745554344,0xC3E627E45CB2211B,0x0F28955867F9C73B,0xD5AED38996A532F9,0x93B6278561D6230A,0xA46E02600BAA483B,0x5974B44D0E781FF5,0xD853D981270D80FC,0xF30B1F1EC3F465C6,0x1EBB94E97C80A064,0xA69A57E020FA6E5D,0x0DAAC5FF85583C26,0x25BE5341C22B30E3,0x9BD07703174F3F10,0x98C6A6119A2DC047,0x28D4CF70328C66BB,0xC9ED98D04B20D7C3,0xED832245BA709316,0xDB277AB1A1BBFC52,0xDEBD33457FBFCBB1,0xEDAC7EB91F20594E,0x2C6A89DFDD2C080C,0xB13D962833494D79,0x164BD9014B7506E0,0xDBE66D6FE18F4E98,0x8D9CA05F5D416D7B,0x7754A723AB29B440,0x76273CA2CC811833,0x9DEBD408F46C3861,0x0276E9889AADDD00,0x468CD4FD3D2A4521,0xDE77CA909E59CE18,0x630C8DDACBAE3643,0x5B541F5480789AB8,0xB4483EF619344D75,0x0917678C32C650E2,0x1F2638B1838AD7DD,0x341ECEFFC87BC278,0x54F0F2A1374AA0BF,0xF770F30928E91EF6,0xAF61D12D1279982D,0x92B4F786A7ABE407,0x37BED1A8EA3E411F,0xE5AAFFC562A66388,0x05B4912E14D30ED8,0x57051BFEB231D579,0x0A7F3BDD13C319A1,0xC369602489377E64,0x450DAB286DBD8D41,0x174CAF932AEAE90C,0x7D9434F7EAE1EE7E,0x3EBB6CF6A9D78A23,0x0B250FC64FA845D1,0xDCFF0B5F5AA697BC,0xC32D411FF028E727,0x866441C75820FCC4,0xE801B73BB6DECFDC,0x5178C63E66B796CC,0xCD4CC5115CC4A2C3,0xEBCF261A73E6993B,0x9FB360CB3B4B36AD,0x25A3EC3276FBFB80,0xAC779337EF4542A1,0xAC4F944B431C9799,0xBC3EE992E4847DFB,0x72ABCF17B18074FC,0x6FDC81B5FF1B3858,0xE91351559CD6B431,0xB3AA0DAC8E2AB9CD,0xB2404E4EAC9E4558,0x6C7B788DA79278BA,0x971CA24F9EA00D43,0x4D526F97519FC634,0x5F3054CC8B72EB31,0xEAB3CAA56EAD5F67,0x6303C3B126DB976C,0x8E8B2F51B9670745,0x7A8A84C95DFBF0CA,0x54894C334FACF193,0xB816408529FBA2DB,0x0218CDA51D144170,0x33D4E39C8A2CFDC4,0x77355C2A517BC8D3,0x6D522F3942142654,0x93B0BF47346FFE1E,0xE83A843E24F79189,0xDE76D2F68700EA77,0x31F7D0CB06E11EB6,0x35F344912699456F,0x47B5460181C65806,0x715EBF9687EE0EE0,0xF4CAB16398AC2F0D,0x5978AE1A8E55F453,0x7F79C101078BB5D3,0x1058978928977D57,0x0AF6A0EBEF34D8D7,0xC86FFFC9CB1B19F1,0x09EEC8384EF163D4,0x3FC72D3B6F06E1A0,0xFFF4349BAF987DEB,0x9E27E90381071F5F,0x6DB09AE15FF1B2DC,0xBE9190FD0DB8C957,0x0EAF56D0E6E5295A,0xEE20A56A05104FEA,0x8A495B2214B368E1,0x884BD7C31549B927,0x770591941B2F3AE6,0x8194EDC4BB8CAA18,0x8599FACBE53B11FF,0x6743973B5EF8522E,0xFC0F56AB4C2E0506,0x495A9267D1F8F6A5,0x8B2E885D622ACD6E,0x9D0B36CD625EB8A9,0x1B80067425E07EF2,0xE2447F8C476E34EA,0xCC95C975D02D0241,0xA9713351EED463AB,0x8AF49573DF16AF64,0xFC17F901FE3879D9,0xC1FEDA2E1ACF6F99,0xD2C4B75135C0719E,0xD5FFF42E11B6354F,0xE3F53D32FF8F0E3A,0x32397376453465FD,0xC9B43C76FE8C20F6,0xECC152C3C0590610,0xBA915AB75DD456B6,0x3939F990A279AAD1,0x19B925F718B3FC44,0x8189B8980AB78404,0x256177EAA4E47029,0xC2AA24C7E13D245B,0x373D42748B55B15B,0xBE84F233D2CDA9F2,0x4F49CBE4C6F6C2D8,0x29A393C9E9B69103,0xDAA6EEDC46D9D718,0xE6C728C526D054C3,0xCDE85B7955EF60C7,0x280386634801D7F6,0x815E28D7057C41BB,0xBE97AAFF17D34AC2,0x41FC8102DBF9ECE5,0x71978680AE946A6E,0xD6BF68027D6E3EE9,0x1B24A9A4EFFD0EAA,0xD54E537888CCE474,0x01EAB7E5AAF4A6CB,0xB6E415E8482A594E,0xB93375AD2CFF35F9,0x1653A462D7548DA8,0xA493E02E7DA97E16,0xE78D313D4DCC1707,0xF969AF6AF446E1B3,0xB6F7394A3DE77B2D,0x4ACB42A8834266EE,0xEB3478215AEB55CF,0xF671766014071CB7,0xD9EBFDA8D6F5B507,0x53AEBF6B764BB19B,0x66F7F845BD5EB086,0x483D3037B6AD8566,0x68D78DC95DD1E9BF,0xE0678DF7D2797A1F,0x06839C1776104460,0xFAAECE20760DD6A0,0x46DB0AFF9567B678,0x0642925BFED0B501,0x0856289E468F264D,0x0382F05011F13082,0xEE66B456331C1249,0xCAD29F98C2DCF03D,0x20F9518BBA1584E0,0x9FED1102805524E2,0x27933A1A7564CC50,0x446225518F51BCC9,0xBE1B61CD202F73B6,0x4BDFF1888A457082,0x1D56941AABFCAF72,0xB892F85F81F0D4E9,0x057CADF074B75B17,0xBAA825A28E495760,0xCFA3896C1802B265,0x6CE6537A3041C9A4,0x7CA8C4937D488216,0x82A399D0236CFCFF,0x32CD46E75246E300,0x5EBCD09293F2CC0F,0x0D00EEC24DF64CD9,0x98AA908B2DCCA685,0x31E9492E762EEE22,0xB5487FCEB020E874,0x8839B34D9D6A0D36,0xA88B4218FECE9751,0xFF5906B3723B4DBF,0x4D64394D0FDDA9FA,0xE5F3CF5AF36A9479,0xB3BBE96C3828DA4F,0x3B95F6F72736F0AF,0xDBE0E73965503F87,0x23D0F7DAC72BF2C3,0x6DFA57D170361C66,0x299351092918C563,0x4740C2A351B7DF2F,0x9327B093D796A4AA,0x6C57CBD8D5DA88AB,0x86C8572D1CF88EC2,0x574EBC22E7EAE328,0xDD8097EDE81731EF,0x7BDF3FD7ADE0C337,0x939775E0939E21F2,0xF0574BED5A1879DC,0x6091DBCE4A533970,0x8A20A206F7C9D7BC,0xD697B98AF0D021EE,0xF0BB55AB4DC52227,0xB7F7C4171A3B36AD,0x8E3C97DF9F5BB7D6,0x265DF345732CF96D,0xB9F61F4227096EAE,0x1FF816C0F5426A4C,0xF3B79E0601D5429C,0x3A60F2774A162597,0x6970D336D0332FF0,0x84405ADE2915402A,0xDA6CEC33F1D97DA0,0x84CBD75C132E3697,0xA6B7883725DEE932,0x4DA3E6040DF1FAE6,0xD515E573B5993043,0xCAA0DA0E78D93F47,0x9CD9246E6C742713,0xEA609BCBFFD4FD3A,0xB823E286C0CA0608,0x205E0433FFA9C169,0x0D9FAE92935ABD2B,0x9563640A3F69781C,0x6EDEFF8B4E5A8367,0x2713D99B2F41B517,0x1B3E11C5F225F25F,0xF7653768228C8613,0x8C3023BD76CAE7D0,0xC6F1A757F8566FDD,0x65DA1DBE3AEFFC18,0x0307828BC97A26CF,0x85CEDD2D2F4F5561,0x8101ED2949AE5480,0x1B52BD6B9D75E5D4,0x53F5F4B68EBA40DC,0x6C99EE6A16D45B31,0x1911095F33F2A8B8,0x1D98A4DB3C7E3710,0xF658AC74F93D946A,0x41001A4034A87451,0x707C5A057E990F06,0x93A6CE20FBA38214,0x2A47539D42DECA2D,0x30EAD74862313A75,0x2384838B22656596,0xE414B37EEDED821C,0x1DBC2AE7454FE3E6,0xA8266D49FF552D37,0xD24D8B77C771C758,0x6B2B4F0C77B376DC,0xF1A026A415618815,0xD74F55B23578D711,0x1250E433311C20DB,0xAF230D4016FAFA39,0x10B3DC415077829A,0xAEB4C07CC3EAD9EB,0x7AE3C4C3224ED8B6,0xB11FA68EF24D4528,0x3C7BAF89F277A023,0x5E6FD7BDF3ED675D,0x2751BB18252E7C0F,0x22C32516CAE0A6D5,0xAE9A9A9E69544C2B,0x83EC126FE0D40A50,0xBAA799451731BA11,0xBB464A1F6FE3FAE1,0xA9A7ABC8E1FDBD30,0xBC92A97FFE4F69B5,0x30054ED3AF59DCF0,0xF57A4817DF9ABEC5,0xD36BD060BB4E6467,0xDB8AAAD0F51686D1,0xB261B5FF5619E0DA,0x836E9FC7945DB3EF,0x6B57A32681C8C56E,0xCACF6A3708815F2A,0x273A53FCF570752E,0xAFBF694329E089C5,0x58396A44DAA9FFE4,0xB20C9B9395997055,0xDD91F8FD9BE00225,0x43B891164C6BF6FA,0x5D2A309D70B8DB11,0x12B55FBE5B859EDB,0x638BF2853B76D2EF,0x9A860EBC58E04224,0xAB3570F93C8293A1,0x90E100A62A5E4171,0x7B8E4F28D8EA3FDE,0x67D0121E85A24F46,0x510DD851B60F2E22,0x741413B8AA81CAF5,0x07BC1D9EFDD6EE23,0x60993838E3550A76,0x3164FC93BC8780A0,0x1B477D5027D0D32A,0x5A8CBA47FD8E4D48,0xE9793B22E9AAB68A,0x1E4198D8D8403B17,0xACF6D6CFD97B82B6,0x0EE3329B13B55DD8,0x1417DE274D2E5D4E,0xDAB7D7B0A0C892FA,0x83D04B2F81560F5F,0x73828B3816609F15,0xE4DF2A66098417CD,0x3529057665B837C5,0xDB081C7B25BCB7BB,0x6454887D725A59CD,0x60E0A8BC04F645CE,0x36C91B88D142BC29,0xE4876B1679D68EAA,0xBB8D5F6409B5617A,0x420C670D3756196E,0x41B9328564A01A38,0xF48F5CDA67856D3B,0x1449D706023990BF,0x843AA73C13757F23,0x01D254AC7021E0A4,0xC8748D29F4456243,0xA8BC594D5BB09362,0xC44AA625338F89CB,0xFDF9CAC71A05DCA2,0x39E59FA8354A1FF7,0xA50520462EDCABE7,0x91ED08E58F77F094,0xA45491B1BB59F004,0x86A299B7E0F657A8,0xDB559713F0C1AE41,0xD6A44C2741B4487F,0x5B57825365CABA7B,0xA78B2CF096A7FCA3,0xEC6D0947E7D7C31C,0xDF3554AF0C678FF8,0x719CCF11630D89B1,0xA1A241A43839912D,0x91D2E256A7AC205A,0xA8D37B6C6A3F472D,0xA3E6CB84202AC9FE,0xCD9E2C13F67A0B19,0xED1BB1597C11F863,0xB72C6079EE1C32EA,0xBD4BCE89F2BAEF30,0xBD84E5BA144730D2,0xC13FBB978FD84C70,0x3A188974AD85A3B6,0xB7C7282F71DF5FDC,0x29B787CDA34F205A,0x16D369002B908D91,0xC53509ADAB56485F,0x1F5F4C114BBBE1B9,0xA0EFA774D3346CC5,0x62850052EB24CDAE,0x3681C69D025F5889,0x7816FE36F0D3EA80,0xC8DF8210D25640A2,0x6E21E32167E82208,0x687D5C26C0527135,0xE63FAB43C9F7E534,0xE5D0896BC0705973,0x72BED5AAC33B0ED5,0x210E35F5DB58A455,0x56B690CFD3F73B66,0xCD983CF2DF3BC232,0x4420A536BAD06222,0x7A45A1778317FB84,0xC22269BA97C50F10,0xFBC9FF1F34D416A0,0x86633DC63D50650F,0x06E01F0DD0D048E2,0x52CB9900488A281C,0x8F2DFBD9532B37DD,0x42A1C59A3AA44B6A,0xD5F3362F64B76703,0xA9772CA1DFDFE2DC,0xA3ADDA98F9B9FA21,0x2B18B059C188933C,0x1367788F8D65B8D6,0x2BA57D655D68C727,0x37DFF755FBA50D8D,0x01322F53CB82AD14,0x918BB5D5E95C2537,0xFAE0B63CB794AD86,0x58E99D0E415C0F76,0xF5D8BA73561E5035,0xF1B55C57A5A6E790,0x00C1564D5CA9AB60,0xA41CDBA2AF1A42A7,0xDA222C79A9A6D07D,0x6D213CA6D6A0E68E,0x66824FBAADD1A0F6,0x87833C64F8CE13A3,0xC5DCEC7008CD11C7,0xB1880A8B1E39F48C,0x7C267E98A28FE610,0xE560E34A8551EA12,0xBB890BF0F4ADE700,0x5F11CE5137C43115,0x1600A73E3992FF20,0xC9BE34B2F71ACEE8,0xD4D7A046A27CEC7D,0x65DE70491D2F6CC4,0xB247DCF7AAD7DB8D,0x7C5442F004D58CBD,0xDAFB9ECDCDF754ED,0x3C1A333C3A8FF854,0x3BB4572E9FB7BF9D,0x5F8C842DDF842316,0x4ED2098AB77D413D,0xF3375043CE112200,0x3A20AEB27272CBA5,0x7D8C1000BE42F113,0x56F099CC684B6D91,0x4252A769735DBA4A,0xD2B96B08E09C7A28,0x7305B7BA02A59303,0x4D1CED1F3CF310C7,0x87996829ABB04658,0x8C034D12F3AFADDD,0xD048D540C9FA857E,0xCEFE19D67D1336C1,0xF955841CBC96663F,0xB4D9367CB47E5FAA,0x6D6AA1B0182B2AF5,0x902619FACF20A1BC,0x9EBF17C1AED57855,0x6612D9D70A36BDBC,0xF1EDEA58F56E2019,0x82F9FF2313D73618,0xAD35B2877A4D8DA3,0xAC51614E61F7BB90,0xAAAAED3A6C3A9F81,0x234791020256AC2B,0x65ADE702B2C3791B,0x44798DD4EA923E77,0xD3F5E61F2D784042,0xFA07407BEFE452F6,0x70BB37599AB61019,0xBFFBB7C3CCB8FA2A,0x9C647C11F784DCFA,0x3BFB314DADFB962B,0x8F80BB9880247D5C,0xF4DEFCBF372259FC,0x75802835542E4836,0xAED9858FAC0FF611,0x18F3F3D94A0E5001,0x106FD9A4C3790760,0x91B0411FD644201C,0xB8B5D16EBA192CDC,0xAD2935AC702AD876,0xC099F19EFE625DE4,0x6A6AADA2C465CE32,0x0FBFCE67D0C92E7C,0x56572DCB5C66A59C,0x5096C68D2C496771,0x2DA36CD8397EE311,0x5B755DEE702CD122,0x1FF6644BA9A91757,0x0F95634FA314525F,0x8ADE7BA56B07CA5E,0xED884C88A31B3A24,0x38F70158D2F45830,0xF5E102B7C37DA54C,0x39A352C779D3EC0D,0x5034B0592713D382,0x9303B72D056C43C9,0x13032AA15983EE02,0x653ECB46F47E39BE,0xD1BF2E1884BD6FC4,0xE3BA15D031F0A029,0xA9C345485179CD4A,0x161486F56288F4E1,0x50ECE5827D1449A9,0x0086538BFFBD2252,0x6D277E26ECBC233C,0x2D1C45BEFD87653A,0xC1D984989D5DEC62,0x3D8BB57E9D35BC37,0xAA9007FFBB280081,0x3036602E4FE165B3,0xD1B26C458A57F9E8,0x56D222AE5DBF62EF,0x0CF88C80C0AE09B5,0xF77FED17CA1ACEDA,0x632E3E2B0C5972BA,0xBE9A0F9DC735FC78,0x9C77942D3488A743,0xE65559DF4A6BB77E,0xF7CD953E60817F46,0x2DEBEB5953610BE3,0xDCC7D9DB26D5141E,0x255AF50ECDDF75A5,0x40037D089247C999,0x3D5101C9E56AE326,0x6DF82ED99A1CD1B2,0x4FBDCE6A9D0DFA9F,0x8E3DBEFC6B8305AA,0xD955134016D57251,0xAFF1F5F1E6C1AB32,0x65E783A13A46ED09,0x5C9628CEB6A26CFC,0x174096AE80585A9C,0xC0810D16B9FC6F35,0xDB07B3C3E45FA90B,0xBB8F4BF77249A934,0x85CA779B8257EB11,0xAA9F9E02918F2C9F,0x234D979262C98C83,0xFF5C876121C8689A,0xE6004709A6748618,0xA331575D796284AF,0x397FB052A42F35AE,0xCCD11225D1E3AD41,0x9CDE013E88CDE871,0xB97D1B80C72C60CA,0xED2D504C23AFFE83,0x70B04E8B5370A6CD,0xC76A7B617C21D110,0x5CD757DAF77B662C,0x394AE067DFB6C2FB,0x23A643E100D72757,0xFD1718166E3B1D17,0xA750DF00DADB96C6,0xE23FE94012029D5A,0xF13A8720D683A664,0x150677891128FA22,0x64F046FB324B595F,0xCC6E676D23611405,0xB04048D45F446081,0xBBEE4D769F56565A,0x4F651AD9639DF5D5,0xD4BEF402E25DDA7C,0xC261BD882366C9FD,0x6ACCE7F616171B94,0xA8FE0073775BD975,0xA625B551236EFF11,0xF6EAD7849CFC8606,0x7A4118D753EEA34B,0xF9971C64CCD721BB,0xE5020A5739075B03,0x2CBEA20060632753,0x95DCC1503A14880A,0x26EF5CADC25E1B6C,0x6A40238EDCAF45FD,0x9D389D03B32D8EB1,0x1A83768637AC9BD0,0x6FEE4DB43822A05D,0x44E0294869898019,0x4A8C9912996F805E,0x06183AEA78EEE59B,0x94ADB217F6576BC6,0x0D55F0CA350341CA,0xCA8A1BA5723F200F,0x9F6CF2F9C8DFC09D,0x014866170BC8CB59,0x4D5E8CC4E3C41294,0x4A2925B606412A38,0xDF7C4B1191E9B79D,0x8A82EC8C2A0C5410,0xEF17BEAB556EFBE7,0xD9FBE39B7D73B376,0x1938E1DD6FB453FD,0xBCA39CF75935232F,0x782292443CCCD451,0xF5E8C5A5C89ED979,0xC281A775B5772924,0x9D5359AFB2CF1309,0x59FF8B2BA53B42B7,0x46BABB061D87AA18,0x58F3DFE42878B852,0xD92274C65A3CFFE0,0xA4137632026323C4,0xF08F33C62598C8D0,0xE517F65DADC92133,0xA536A07542140921,0x5C11AB5D9DBBA887,0x067FE2C19E3A50C6,0xD2D26377C4FE982E,0x748DA234AC6B45FE,0xF88DD061B39D9F51,0x44800B9ED19C8882,0x9F6EA22EC1AAE01F,0x46141AD87AB6C541,0xF6788F2C689CD24B,0xF0D5E899059F185A,0x17BBA3734BFFF37E,0x0D99E4CA30EA3A26,0x9E253A768FCF1224,0xE1276452A420DB96,0xD596688060EE7EA4,0xB2F8DB94A13767C1,0xF4F58F85F5DA28D2,0xEE3CF68072ACCBC7,0x0F774DE563FF6D8A,0x0C1A34343FFC795E,0x256A125B30AB5F7F,0x8FC9BA8622652F3A,0x916A2B4A0C385D10,0x1F743020BCA75A2C,0x2ABAC36B38BBD209,0x5209D88A00130DC6,0xC7288F3EFA47D96E,0xF23A7FD433F466A3,0x62754556051B6351,0xA475A3DF362A7A70,0xF58E0C165ECE7C86,0xC3334C82F455FBC6,0x56AD3185E27A35D5,0xCF3F456209DB5399,0x9EA9F38385BC8E2F,0x12E59450D776A331,0x1F6AC1CF5DA9029E,0x65A641D7126EE91A,0x334198C1092C41B4,0xDA2916ACA82AE19F,0xB3BF5AC6BD761E6A,0x723FC0FF0435AB2C,0xFCFD9991A13C990B,0x66F218523B40A14F,0xDF4DF079D153883E,0x5F3AF8DA6B56AD77,0x59D55AFD2EA376BA,0x9D3594C440F10C2E,0x0432CD921F77E3C1,0x48EC0842B29ACFDC,0x9BA6144B499E78D7,0xB6B64C25B102E8EE,0x966F0A2661D3E15B,0x140EE8E9BBFAEE9A,0x909308379C0455DF,0xFD7DCBF3F7080E5C,0x0BC2D707A07280C7,0x1BE9E8029BF3BD80,0x7391B25214376D93,0xB32E73BDF6BA63B7,0x66ACDE82AD429E8D,0xB39484D0DD7AF64F,0x6789CB383A6F3CAD,0x997468608B1A8988,0xE861D6D99F4E262C,0x8937F1C43121B88A,0xEDEE6242F72984E0,0x8A6C5697E4294F56,0xEAB07F440DC3085D,0x365C1711A02B807F,0x65260CBB70C6ACFD,0xF182F625E38BCB1F,0xBFB4696B372B4D62,0x9E93EBB7ACD85039,0xAC98AFC8250DA25A,0x18DDA80F35291635,0x768EE2DEF367978A,0x07D4277EDFFCEF5C,0x26E616FF197FA660,0xCD1C0B645EC04266,0x738FA2FA9811A034,0x3372237802A3BC28,0xC966DC5031AD3255,0x996D00BCACC570E7,0x9213BC0A884A7817,0xE68450EF49115395,0xC2F36CB2260DB0CE,0x625C6B270627D18F,0xDC8FA3DA046CCB42,0x3AB4515AB9D577AE,0x6C24A0CF38AF4FAC,0xD06EAC9CBD698A37,0x187F0198EE77DC82,0x86E215E4E88DBCFB,0x786F58894A8B8F62,0x43C468DF142ECC0A,0xE31FD6A6D3FA8110,0x51E378EACBE68CE5,0x298741ADAEB87BA5,0x594EED9DE25730A7,0x2AACC0A605964E85,0x7C866C87035617D1,0xDD77E856F8B0852B,0xB8740A79038A59A0,0x451F6C9715D89F75,0x6C0B5977E10B29CC,0x17A8198B8690FFEB,0x5029F0CA779AEBBC,0x902AECB56DD726B9,0x063333D569022545,0x1A4BF10BF4BCD652,0xB1B054577899FDFF,0x1F3287449EAC74CC,0xF54AC09B66C27ACF,0x7B6CDC568DD6BBD9,0x0F88E97FF8478776,0x25EDB6AD621E0E3D,0x11B4AC509B4A304E,0x7480857CB2E89102,0xB000EF7C0E0BCE9C,0x1157F731011CF089,0x9158478834CBB193,0x9AF7B1222255FB05,0x32928D4C04AB587E,0xD98FDC121632C603,0x712378363F538C9E,0xA61FCA683406672C,0x0CE6D6C7AFA14D97,0x8A4DEF7CED1CFFF5,0xC11618A259BEB6B3,0xBF4E5D81E92EE836,0x68C83D72EBBCB6C8,0xB6C631F0B25B2790,0xE45197276F8F290C,0xBDEE6979BA2F76BC,0x74FF9E985AD9D700,0x4D3E542EB05F921F,0x565CD1FB45D648AD,0x76A0F616657C9F62,0xE4CCA4B7579D6413,0x1C1C17D6B85ECADE,0x7CF42F32672D5965,0xEBB852F977BE61EE,0x91806EF302569ACE,0x007F65655455E135,0xD13480A7CCFCB205,0xA82459B5BA92F955,0xE97ADA3BB62775BD,0xAD83A341CC4DBE01,0x8D98F9630AB6B7B3,0x8AD5C18E651EE58F,0x26BB0A8D08743DFD,0x63046F7741672CC4,0x50DFA2890BA81D25,0x3A73A3E97E637C25,0x0C93FCAD8B6A5FD6,0xAA60828D88C08C75,0x944CC85E6E75D9D1,0x5D582648F32D93B7,0xF3B5A6533C3168C3,0xC27B7D5E2863044F,0xB9A1363DE99AD0B5,0x9E6FDF1267E59D3A,0x26700BA697232B3D,0x20C0144799AC777D,0x35D16AAFDF4CB142,0x8C7F1C312F2B5A89,0xC5FB71666B818C30,0x2CAA0FB5FAE38870,0x7A60478090486E39,0x4484DC078C3152DA,0x6316FBF39A829EBA,0xED6B7B11A0CE3594,0xF9F4A051B4B170A0,0x9666536E1F0A11EC,0x4B55788C0349A415,0x8E2E54D5B4164FB3,0xC91F302F771AC88F,0xCD13D9C34E58BFC7,0xF1E048C2BB6A2109,0x7CB0DC198EB38099,0xA0EB591A3C4F73E7,0xDADAAB6C863BC5BC,0xE2A87C701F39B88A,0x6B07C8C2DFECFA39,0x3A29B619294E40BB,0xC41C26FA7AFB9301,0x06D2BDC69319FBDD,0x588D2BC4F8CEC22D,0x8F4BAF8E2FEC2A48,0x505A74585C7CA5C4,0xFD9DAB1AE23AA299,0xF06C21637C0919F6,0x5D53BC0463A273E0,0x922EA9A3568BD628,0xBEFA75CC45F0FA33,0xE4E5CB34910B2DA6,0x82237A62A5FF8DB7,0x8BEF0C74D774D4FE,0xC48F14F829AB9C19,0x1E4BA0F972E0A0E2,0x53CE9A1D58AEAE4A,0x93371A4E166C355E,0x3BDBD6D8E37045B2,0xCCF7E74BB27987F5,0x66008DAA062C6C4D,0x066F4BF2D3D6F174,0xA06310A29BFA3FC8,0x47C5F638568F44D7,0xF2B7ABF1E5CF8FB4,0x9534502EF916EB35,0xAB496195138A913C,0x2A6D6B09FFF8C551,0xB0E31B2DD866D88A,0x11F42D4BED35882A,0xC559C0558F6EC188,0xE19F5828F15D1B36,0xDE66E970BE09BE34,0xDC3965D8E5101E11,0x64AF7536970D94FE,0x82B2559B4A577181,0xDB8C2214D7ACEF02,0x14D702501D360AD9,0x2F7826CF16F98D0D,0x6A796343649C37E9,0xF87C29855DBCB0F9,0x9D935C56B8A8168D,0x1684EC16F8AF2A2D,0x0692C46841988BDF,0x43512C12E4DD27A6,0xA287C9F792A62D90,0xD214F41E48D3EAEE,0x66C82DD037A6167F,0x174B53C9E58E9919,0xA351AB2A470020A4,0xCFB8FEBAA7CF7D81,0xE195B0F50D0C7887,0x75C5882883A13FCC,0x077728C92F5328FB,0x0CFE34A22A92EE68,0x0D8C901B3EF0A115,0x81A43B5AEA27F8BF,0xF7542D7763AF4023,0x2D36328A70264402,0x57F27CFFB1948908,0xB8AB7668696C9F1D,0xFDCC2FCF41F5F2C6,0x899B53C045C163BA,0x20F2D4004BA61B04,0xBAE3B379E0FD9C38,0xCB861463C0D3A487,0xB4AEE9C3DB0C47BE,0xA9FAA765981E79F6,0xAF71693DA306EF1C,0x50E897D868189C5B,0x92206736C99F2434,0xE3186BEFF423AB02,0x58B01780790A6439,0x6C28892D13830124,0x6352B3F46057DE78,0xB642471B6935B797,0xE334730677F6C4C8,0x9B508CF7816D90AB,0x939FE4F60EECF21E,0xF7720DBD42397F11,0xEE5DA836F873349F,0xC3FF69FF12FDE2CB,0xF562D0D305B2E45F,0xFB1B74EBB9A9EDBD,0x87013A64E007991B,0xE084A03BA539501F,0x4645CBD49FE26D86,0xB666094890D54313,0xFAFB46C7E7CEF449,0xFED9A3BDF15CEC5B,0x71DA53DF85E59205,0x02094A287D9306E1,0x3E21F953ED4EB373,0xE9C09DE0E1FACE2A,0x85AE3240455D53B7,0xEB7F701D5E963456,0x1997B91883C0740B,0x51DB64AD78146341,0x85C731DE70617C92,0x88AD2A2C9C118F84,0xAECDF0DC71916672,0xD2F20621E4073B6D,0x8B3E2F99BDEB2292,0x0003487930B0C0D6,0x01615FD2EC5BE0AE,0x56B1D3DDAD2CF734,0xFC7AEC662425B15A,0x1BAE27FD110DB154,0xD3500E2FFABE4B46,0x4C99681D99908316,0x9F4D0FBF6BF5CB5D,0x648FB40ECF267524,0x686C618E08408561,0xB15553E76DFA930A,0xB4F5713EE2F4D5C2,0x7D88EF48D2CA1A15,0x28F28487E849F133,0x638A2BFFC89E8C14,0xAECF516B7EEB2B43,0xDA2DA06DB193E7C9,0x659FE7DE9EB2743F,0x76FD6A554E8196A3,0xEEAADA4170C34EA2,0x2157863D72D0CCDB,0x0B1BCA7F1CA1C9FA,0x70A2E684D6C48417,0xD49300002D2A3D0B,0xD31A5DE13BD17FC8,0x00F0500DEAAB1E9A,0xD205352BCE7A9423,0x0F444E13C70DB27D,0x4FAD02262B244383,0xA95944C16CDA1AA0,0x48E4FDFAE9A23075,0x37B26D526743B17A,0x57FF93E75916DCD5,0x3A094BF99E34BBF3,0x6DE032843BC58AB9,0x7E5806584AD8CEF6,0xD4AF187F1044D9EB,0xC79E9EF02E95FE23,0xCAA3E0FD5D2D1ECB,0x160B8B875E081086,0x0E6DCA93992A7115,0x9480421845ACBF76,0x027E9087D7AB63C4,0x859DE86270A12DC0,0x2A0F09C5CC85C905,0x7CA6EAE0678690E9,0xA09249E1AD829867,0x8FE8B64348251D07,0x26A1642DEE77C8B6,0x6E2F7EBDAE2A4367,0xC2E5FE1677764D11,0xBC7169128023C6A2,0x4A9B63B5F188B936,0x803AD7FB1F8051BD,0x659BEA54AD4126E5,0x1EC69C1581F62959,0x00204E03C85F58CF,0xA74D115A95A51E26,0x71EAD7DB978C6B93,0xAA2DAF9FD35B310A,0x18BC14083332A3B2,0x97A1B5AC48AEEAFA,0xACAE3C9AB8C22408,0xBD16B2957FA217B1,0x315C1659B3535859,0xF568C36FD8B6D5DA,0x9E2267D6E581EC1E,0x11D2544466B9D3EC,0x890B1340729E831C,0xC24502815D6CEC9B,0xDA626AAFC5612B25,0x64010D0E11CAA077,0x46F3394EEB5A7949,0x7B06113D7B7E3F4B,0x79CE2E4694D9E227,0xD7A92FED078E6053,0xE8F87FDB81FDA12D,0x0374C8D52034E3D6,0x12F2229CB8165B22,0x257184E4EADB51B0,0x59E7888BF32C4DE2,0x3735737FD442B4FC,0xB5D67050FCD09574,0x00BADB535D62EA0D,0x3277B1FCC8A2F1C6,0xAA0FBB0ABB44AAFE,0xF5690CAC91141CB0,0x5CC00F551C8240F6,0x2EA4E1A8D51D1952,0xD657EBD6A2C862E5,0x563AFDCF0C27F26C,0xA398ECCFFAB8EC70,0x4589DFEA2366BF14,0x24F290F744D2C0C9,0xADBDEFECF4E631F5,0x783F1F97739E5F54,0xD1E56FE7895C6F75,0xE0DA377BE99E45F0,0x45F1B7854D81A411,0xEACB2FD01EAB129D,0x79C3503836E53411,0x236E61107B2D78D0,0xD098CB7D4987C874,0x004699A198162141,0xABC8F616CE2F710E,0xF0265B7183E84E10,0x6254A5E11D264E25,0x7F8568C156336EA5,0x699AAD5EFBDD3BA6,0x1152F7B12948E943,0x14FB0A0E1A98AFFA,0x07D0D3DDF489E5A2,0x0C9220B6C129ED9E,0x6D152AEAB0D78E5D,0xFF291EFA77F0FF13,0x35BFC22B442F1216,0xC66D435DAC33D010,0x71E0EFEC25CC60BA,0x4AD64814C4B981E1,0x02DB0F55EF9F627A,0x449099A3062954D7,0xA1BC0F326576F8A0,0x56C3F6E3A143C8BA,0x9FED55FBB1417CBC,0x4A17C96DFAFB39B7,0x5C7D5DD3C34386EC,0xDAB0E7EE2D3D163B,0x12047055335A0CF3,0xDC42B1D0A2DF6A89,0xEA81DD0E674858D4,0x4E8BBF43F5DA71A7,0x13B8C9C0391023F3,0x1B7E71B8FBFE2B50,0x541AA7AFC792DA7A,0x4707268DFDA40867,0xC73379AA4E560593,0xF96B4AD4185A53D9,0x2F9106A0BBAF3F81,0xE0285E6842E2213F,0xA1D0F0ED40BF6771,0x8CF1C257CA1753D1,0x0B7114D63238FB54,0x25ADA7F4246B76B2,0x4D8C485A7E226D77,0xD31C635650F0ECDA,0xF0D6C5FB7011F27F,0xBDD54AA05E646529,0x5787885A666B3E84,0xCF18638C964F67E9,0x1B5A13108437441F,0x137D8F96CD909F5D,0x77157A680BCC97CD,0x87B3ADB9BB957550,0xF3A9EA6F0010B32B,0xC0D00889403F303D,0x076920CBBF4CBE98,0xB9A8D51C7D1AFEF0,0x382D719C492517A7,0x2EAA106C6413E9A2,0x989019A74AE41611,0xCAC36D1448701EAF,0x3F7A4C3838DCDBB0,0xD51613962AACC3C1,0x0EC45641CADF77F3,0x5D4759C69B7441F7,0x26FD377041D1EF0C,0x373A6F74243793A6,0x352A1587B28D7225,0x622C4EDC7F2B48DA,0xCD2B51AEA373AF9A,0x7A2C7B28C9EB6B1F,0x085D302137E903D4,0x2B1EA4B4350B2911,0x7CBE89BFB2CE005B,0xC27A89724D3766A8,0x10584050035FEE30,0x9D4851848B900231,0x6310BF5F60431E5A,0x6AEA6C534738674F,0x639F84D7885DB356,0xFF4DACBDFEE28F7A,0x0C18D4EA9DCE81A6,0x3AED78193DA83E3D,0x0652046D7AB32E78,0x4AE49438D134A9A5,0xDDC3D8CE54407ED0,0xB2BDF951A06DD529,0xBAFB19F4EDB2C191,0x47BC86B91F0EF739,0xD7AB553E9D98EBDB,0x61AE2696831F1BD2,0x971729185E5212C0,0xFBF4FB113799FE2C,0x9504D566215B787A,0x278D29D2CBA32BB0,0x8EC019C2DF0787A1,0x154E2FB40A275C23,0x2FB4602C83F6FA80,0x36EF97A81DA108B4,0x9ADD6F36B7FD36E0,0x5C44FE96031FD435,0x5B52E62699F59574,0x4F65D09943F76A7A,0xD5A2D3EF4DBF4F49,0x3B0396D4D430FAD7,0xC65BB55DE8BDCA8D,0xCE41CF0E564D861A,0xA282146D7990F8C5,0xA35882197103248A,0xCEC2E6E4BE8EC9A7,0xCCE9C32F8C2D9C53,0x18BB3C9CD3848F0B,0x265ADA3F5CD3301A,0xBD93324BF8872CEF,0xE30323EB26DBAB8D,0x5AF4F983122E4396,0x9754C0F5FCF3AB00,0x2EB0A55053CC3283,0xC9F40780493D5EC7,0x89A3AD0580BD1E2A,0x3B817DF378D41863,0xBB069F4C2B93D28D,0x325268AF453E6FE7,0xA73659CA5F14EE18,0x5D9FD32E9DE99B36,0x8EA63576C60EB75C,0x27159859CED78C29,0xD277BF27415370AA,0x799454C38A746B27,0xD3F7BD2128E4FF8E,0xAA0788B27FCC2195,0x2483BF1B0282FB8F,0x5B9A4915851B1922,0x3FDA9114C892DD9A,0x0BD67684DE26D545,0x326DEBEFE7FC2C8A,0x051A45F644EF7F4B,0xD9A84F1030A1CF08,0x5E3514774E029062,0x1C54FBA183F4D20A,0x4A90E553E85401C4,0xC1961F097E31F6C8,0x89F9086FB7BF8422,0x67DAAD825EEDC574,0x39A40B7656DC037C,0xA7D15482882888C5,0x7A53BC944FF5E866,0xA937824621C358F6,0xA7E43AC5479AD44E,0xAE972E31CC79161E,0xFBDAAD02D2867DEA,0x7319361B9F84BFC5,0xB113B970EFB17730,0xCCDC4EB1939829D5,0x459B7E4D4D92282E,0x00892B342E236EFD,0x2444CD823A3644E4,0x180FC1EF986B1F14,0xC295EB3FC1857A22,0x6455D2E2B13D5DF6,0xCB7FE44986969700,0x8AE4EF5CFE47E93C,0x3512A1CB137D5FE8,0x006CD4FB77434492,0x1341B03C9E0CAAA5,0xEFE69DFC6D3D4C24,0xB1BE6C85FB3F06B0,0x75DC8E88567265D0,0x646543F48045882E,0x0F8C05590020C6E7,0xA8CE1262B5576F34,0x33B43C890C5C865F,0x5C5A3084A51C8823,0x11753B0677AC1403,0x5AB72062309E482B,0xD14DA3D3A0016418,0x5584E4413CFF176E,0x5029E47777230B0D,0x22667D5BACBF9A7B,0x68245A20AC4B0B77,0xB6EA256CDA6AB60C,0x9D0836A0CC804AEF,0x9C8D45B918276F17,0xEDDD7245DF55B4B4,0xC2A8E3E9D52E0D75,0x0325B53E023A02C7,0x58F49ECFF79597C6,0xA2A9D4E1DCEA75B0,0x00308E286492F4FD,0x53127B097C2A2C3E,0xA85F9F7C4D112603,0x8C43C587080B25EC,0x2E92F3BB45B8902E,0x95E3F8FED14CBF82,0xF0E997ACA2769F10,0xB1DE8241863707D1,0x166DAB41E3E94C47,0x4A38379BFD000C8F,0x75659F2DA17DF571,0xB39BA8098D5A4B9C,0xFA8AE1022F29582B,0xA16AB7C3134346DB,0xAD07B40831D47D78,0xB1E55F4A4046CCBA,0x5B83384F7DF339BC,0x67D3418CE194793B,0x5777E094930A07E4,0x2E8EF98DBF1D6A27,0x432DB81E1FAB20BC,0x44186BD725C65C66,0x4288DC2E26EF6CED,0x9BC4402F15CC5B88,0x158612237C20282F,0xE927EE65AAE494AB,0x6A9409ECC2639CBC,0xE968A6E72D9F1F0A,0x61626A20D5BCEF0D,0x0685358E8184DADD,0xAE704E3CF7AD8AE8,0x5AD1CE29BD2F57A5,0xBB0BC84217D9E90E,0x7F5A6DFDC277D154,0x6F4B4EFFEB4B1FA4,0xE9B47691DFD2B9E1,0x90BB2768F9193535,0x8586815ACEAA3FE9,0x9DC69A92F553E5C1,0x9283B344E8EDE7C2,0x6C73A83B5ABA4760,0xE18319C2538389D7,0x0AEF0952A011B2B6,0xC86615C7D4AD662E,0xFD8836B98A76DEF0,0xF457CAE048729E5E,0xDE2FD6495D65E778,0x0D946E7D2F3E899B,0x5F946759305C4DBA,0xAB8F1773C184A289,0xA8317587A37FD75D,0x0BB3E2EF493C05EC,0xA75F8BAC74081D44,0x2ABF5914B3089989,0x5C6DE454340AF79B,0x94535435666F3B2F,0x0E7FE7C4932096D9,0x3945651A0B15AAA6,0x81793C8F1AC72BD1,0xDA537D4D97563A87,0x589CA66CF4A099BA,0x6340E7A2702040D9,0xFEEB619D0C7F9536,0xC364872B582D8A9B,0xADE6CB390C3F1A18,0x5A597202B035069C,0xC8E266A377D4350B,0xA4959C88B373A834,0x5E8DAC13477900C1,0x767BED157DD107F7,0x4D481EAC39389673,0xAA621CED00373083,0xB3AC913DE54B88FA,0x6B76CB12551DB8B1,0x6293B5E9EF3EE7FF,0x953A3F92644C15EF,0x105B1B45B47E8CE4,0x237B866F33706853,0x846ADF6C2D0AE550,0xF56B7B44B9AD769F,0xD0A575125C626D99,0xC574557BB72B7860,0x4088CF62017DCAF4,0x553EA703B471E261,0x4ED024D8789526D4,0xE6DA6F3ADAD1E68D,0xEF6316DDF0A7BBC3,0xEF5230B99C37D344,0x56E48116965EC66B,0x25504BD3E7C37194,0x4B37751432012D67,0x180A99D081288A02,0x502E4157C32605A5,0x4F6CE92754F9CCD9,0xFD538DF17912FA33,0xF53761BB80580BE5,0x1E8D1416D7D21013,0xCDA9AE938C6F8079,0x43F86C89C5AF4378,0x1F3276F6A7703010,0x7A2F9E992A708CF6,0x287175EA3ACFA644,0xAE0496503D7D5E2E,0xD7110F93247365BC,0x6A11E713C2EB7A89,0xFE8589F42CC30DA1,0x89BA2E6C4C73076C,0xE90119449030CA16,0xA8D1916A2768B153,0x09244C48D9ECDF61,0xC905B198DBB78D61,0xE2DA7DD5F4DB673D,0x11A67036F13B2D2B,0xEA05561060223BAB,0xD418209CFBA18EDA,0x40475BF0CA8D272A,0xC8F3BBF17B80D252,0xE0C35B259DEA2D33,0x1AA96DEADA348710,0x680BC84B98A3DC11,0xA374FB5BC03B1CD1,0x54D132E5DEDCABA5,0xC365452E5515430F,0xC0E7F46EF31FC021,0x970DB60E92B10D13,0x4AA6D4086E63741F,0x8CD9B6B059F9EBC9,0x32E330270F0C9F21,0x06BD02FB8F4283D7,0xE6A558CE9C224AB1,0x619A599487449152,0x5FF08573C0E7F545,0x2443B5EB4F792CF4,0x683FA4744EEF171C,0x526219C7D0B7673A,0xAA0021201B37A2B3,0xC6E6C37F25578116,0xFECCFECAE83064F0,0xA5D7CBA9BD266219,0x36A636A89991CD2B,0x71EDA6E11AF65072,0xE80C4B8545C181B7,0x63692B6F0A560A2A,0xE022471760455483,0xC562FE55CB3DD1AA,0xCBEB063322D2F42C,0x16DE6B8919B74A7C,0x6F8C3D74CA1C2759,0x3A3C5803DE487650,0xC281733B4E2E3CBC,0xC622D947C4853963,0x21B8449687B6EC4B,0xD123F317C8E22983,0x5FB86CCED12EB2AE,0x842741927B46CF4B,0x7468BF60A57E0A92,0xF892BE156483CB76,0x550397E837F5BECF,0xE6EA62EE0396C16F,0x490091B01BAD26DA,0x2F1EF15030BEEA3A,0x5FBA87E3E8CD123A,0x2D2D74BD0B265157,0x8BDF8FD95D3DF273,0x4D53F7A05E13EB3B,0x8042504C95718332,0x42DBB02FEC54410F,0x2983AC257CDFDC59,0xA92DAFD58F6C0443,0xE160047504CB4048,0x55CEC2C645823C72,0xD06384E197E39586,0x16E580A2EFD8101F,0x9823575B926C50F7,0x92AD7CE2088632F5,0xCC5059BFBF1640A3,0xAA1A4B9FAC792E26,0xC140643FF4558287,0x09E25C00B644CB4F,0xF5CE89288F23D330,0x47B4D5D552D64EA4,0x4914EEE15D7F9137,0x82E613956406C5FB,0x9B016BA4B4FCC0E5,0xF7188DFC073B5B85,0x81F07F996C4AED21,0x5E3016C171857FDC,0xA3047D452EFEC655,0x4935178B213C1E8A,0x2B915FBACDE79131,0x632FFFB02D7CF75E,0xBE2D47FD1DE386ED,0x5088B098E1264203,0x572B86EE3D73577F,0xB8828EC379158566,0xA6F0B7764C34076D,0xD4C38526526357ED,0x46354975A878BEF2,0x723A78FD5910CC6B,0xBBE5560290106B52,0x91AE5FFA9AC40FBF,0xDBE6C18512573E74,0x350808BD76828B8E,0x60BF549E8448D74E,0x0202289844FDB819,0xBC20BAA9A3BA5043,0x14C022320EDD095F,0xEF8792AF91314DFB,0xD128E790C8B877CD,0x9C4546DBB940599A,0xC5B9855D301E3FA9,0x0373570D19CBF3D2,0x3A50A7CB3BF12D2E,0xD71E3024B8189C28,0x3A4CB368502CCDDF,0xDF791E65777B049C,0xDCB500F056C9CA9B,0xBEF2620C2E81AD0E,0x78FECAEC72823615,0x6BC371A59B647A5E,0x70E8B682DF1729EB,0xE06062A646FB3FF3,0xF8BECFE9EE53D264,0x2D974D3720CE14F8,0xF695BF70056AFD81,0x8AA35935B8CB0362,0x27066E1838739DEF,0xACD7A90EF5E536A4,0xCF6CFA5779D8045D,0xD023CE05E8FADCA9,0x9FA2A399FC78DC7E,0x6EC74C747680817D,0xEC1220219FB19A52,0x1C8931B5395D7CEB,0x0D7981BFE1724A5A,0x84A76BFBF92AA8B8,0x2209B934C62FFDB2,0xF7F1B183ECA6DFC0,0x6ABEABDAB96B4648,0xB7F12B58032E002D,0xCC9A012CAF97404C,0x474BF7BDF3ACDA16,0x036999B1125FD483,0xEE1C91E25DB8C438,0x5AE53919F5C306F1,0xC6805ED1FE5F9FE0,0x877B100CE5561A17,0x0E49916B4B454160,0x1D17FFBDE00C9F5A,0xC33C10F58306CCD7,0x18EBD1220A31BE6C,0xB18E6C84152D3A57,0x835EBE2D3CB81AA3,0xCB01875D833CBAC1,0xCBFC634E1726EA55,0x141B95358DE9F479,0xEC9A2D3F3C238635,0x05A52AB4D080E7B2,0x5DEE864F6EF824A4,0xF37D9F13087E97DF,0xE620CDA3FF63F3B2,0xF07B2334CDE10173,0x13C8FFFBD4820615,0x9766F875932AF225,0xA1E09D154F8CAF5A,0x6DAD380D9F48A22A,0x44045298BBA383B4,0x56881469BCDFA8F4,0x22092DC6418772D6,0xA5FD99325E9436CC,0x180DF1CADA707E61,0x11EBFCF65F46C58E,0xE4F86462F794FF96,0x326098C2D6B95D6A,0x736FBCED2321C358,0x0C7EB01D9786CBAB,0x84237A5560818E3E,0x5EE7925264684367,0x820DC7D689E325D0,0x917EE27FA96AC661,0x140B83DCE76500DB,0x1A5BA60CDA9F5CF4,0x170AF87DEAD094F1,0xD0645712FC76FBB1,0xB16312959A1CE5CD,0x285A5DB3E7573FC4,0x28D9D67BA9B340F0,0x49459AAFC7EF9E90,0x7AA71521B1C5E4DA,0x69B432C40D0AD816,0x830368EDD1A64BF5,0x8E4DF9DDD25DB2DB,0x5295AECD29F80203,0x366374521E59F6F2,0x65D04B4B7D1597FE,0xB315CB6114D8E9EF,0x5CF7531A45A2A8BA,0x8BC7750F4027B7FC,0xA3B00D0F1A70C98C,0x5C0945455C6CBC12,0x53DA08E6C0A792B4,0xF6C75FB31B5CD3A0,0x0E29E3AD758C1FC9,0x07620CA4C91DB256,0x7513E722B4164026,0xF3500EB97EE53DFD,0xCF40196D75367664,0x9B5FB6321B1782AD,0x7BE88F65DC656423,0x50580BCF7E469DBD,0x051A1E2EFBB527AB,0x8A174A01E62E1A25,0x5F22189C7EC330AA,0x3F822254F26E6599,0x44BD14A806E27894,0x7F1C24AB1B7F288E,0xCF06DB47F2BBA118,0xDAB3D770494CECA8,0xEFA8D2DE8BB3B691,0xC07ABB1B2F1D37A5,0x98D31FD6D4FA045D,0x84B789A442C1CE5D,0xC17EC41B678FD585,0xD1D7F2042C203CD9,0x893498F28DBD49D6,0x0FBD59762327DFF0,0x08E3CCBAB16BCDC5,0x7A1C8243E154308B,0x6B1EE694537DFEC0,0x6B76857D651B014A,0x13944F470C0304CA,0xD868AF1493CC1658,0x929FDA0CAEC2C208,0xD85E5CA61F28D533,0xC26CF4F57508480B,0x0C40D0CA8A43ACD0,0x6CB677379BC241BE,0xF1909FD6B80E94FF,0xFA8D48B134F4E072,0x3ED3F167AE2D288C,0x10EF217A98AA5F7F,0x2142154962ED2DA5,0xE7D6578B29D59BD1,0xCA2D85FBA6256474,0x03629C0775768712,0x7B020B084DCB0B62,0x496560ACFCC1E7BE,0xCD3481013F5BD96F,0x2E053098CC1F3FC2,0xC6B01C7A38D09D30,0x39090C7ECD497A09,0x1D6A0C2F6F4BF894,0x4BAAE00EA0B53B79,0x52503570A39DD4C3,0xA09A92CE27CC5571,0xD7CDB00E73DAA848,0xDC2CBCF136A1BE85,0xDC87542760C76525,0xFBEB34AC05EFD425,0x58B565EEDC153685,0x1508D039253E7DA8,0x444EB28408F046B0,0xA7B38C8B0CE8D661,0x1F3F3C48E2FFE5A5,0x8945143BD135C815,0xCADB07D3C629B718,0x3F13D8CBB28706C5,0x82E3A8DB58FF03A1,0x8387785981FF91FE,0xC1089597886F9A7F,0x35545C84130D7028,0xF587140D5F1FA392,0x1D8C2D728DE522C2,0x8A3B7A471ECB503E,0x88144805DDD3271E,0x39A5CD2289DFA8C5,0x17B87832E17BD494,0xF290F57D36BD2D7E,0xAC94AE4B398E480D,0xD8786FC6E6BB15D4,0xB0C85DFFE21E2E5D,0x25C5977BF1BD023D,0xB2F74461035E1EAF,0x5E03A39E96B57965,0x5F5887EF87B04048,0x859F1D02FDF777D6,0x5B41FEE5753C1FFB,0xEA34B106A83798EE,0xDF34ED212E46A9AE,0x44C03ADD23D61CE4,0x2FB2655EC989CC95,0x0A3770215E5CA3F1,0xC06DB40E3300E9AE,0x49F530F9C2E7243E,0x72E83AE524AC75F6,0x413581B4E84E1732,0x68BA2E521E82E0AC,0xF91058802DB94EE9,0x66A4FEB4D2F1A648,0x1CE49D87203CAF34,0x25982167CEE0268A,0xE283828A2A5BE7C1,0xFBA968FA8EE3B548,0x2969E9C579500E5C,0x1755FF88920723B3,0x63C3E911005E018F,0x0F033B8ED597FC6C,0xAB4868BC1408CB2D,0x0405C62E7222D683,0x5BC14B2589F2C2C0,0x78C3813D6B53B19B,0xEBBDABAB2764017A,0x71B9772231153092,0x21315E80A9358E3A,0xB4E05CB3D8D4547D,0x51520DB24062573C,0xD8877E75449CB47F,0x309B08E5BCD7613D,0x422604ECFA30D262,0x1A0982113537277A,0x9274E5B7D2D7307A,0x5C4134364359F325,0x33E9FB0FA7C22386,0x5BF9E31D635262FC,0x8EEDD629BED8CE6F,0xA373EF7DBC2CFFB9,0x35332ED340D9CF74,0x452DF4120850B0CA,0xF95A87E46FE438DB,0x825D45DDD9AF8BC2,0xB448CB312AF22546,0x0FD6D7BAA4EFE9FA,0xF275CB1B3A37EC82,0xCF4A467D44ED575C,0x147BFE528CC66273,0x4E5D8C8724650A74,0x485EC12AEE24E6D1,0x798F650101E27B19,0x2C6BCC9A2BDFEC0E,0xAEC2E587F42F9985,0x8F41E61D2D0FC50F,0xE640EB49DB893BEF,0x548C5FF69354B0D5,0x1030607C1AD65722,0xE5D335FEB19EC0BF,0xD3C2626FA1EB935B,0xE217B855A5B4BC50,0xC1F548434BCB3ECA,0xA089958E278548FF,0x44545358463E4D17,0x08ADBFF9846039D7,0xD08DFD20CCBB786B,0x5428194570A8C1B3,0x4B6CB579874E30A0,0x3A424BBC9D03850F,0x6A6BCB0B881B70A7,0xE6ACEE8777760500,0x3F69E5AFCCCD58D6,0xB020752388139644,0x3C5511A37C02CA48,0x88C632C1B7AE4C9F,0x590382F55E3FA9A3,0xC8B9BF1F5E21FAC8,0x23B173060783CB02,0x38C7839CD8AE3F19,0xECB9A987F6CE3E80,0xE9E78E468A0823C1,0x9833683044F4050C,0xB327F34B93355299,0xD7032281E0C4C238,0x0A865CB70E4A9210,0x20B6969469F0F5FF,0xFF421F27B6606DA4,0x68791ECED87486BF,0x13AE96E05C5F732D,0xB167C820B8FC1DB7,0x45EE7B37A2E82CC6,0x4F45E6BA7D096468,0x9EECE00D46CF1075,0xA91F89B6B792A826,0x1D455D4959C771C7,0x5A0BF1DDD5067624,0x152BBF38FA3EE9DA,0x637721E4249336B9,0xA5C3F7A18EB25CFD,0x55F1AE6B5AF66E45,0xEF4F06D3F0F74961,0xC780CF51970732B4,0xC6A3AF734BE41491,0x119AA2894287F9E8,0x9F98A1F581FB1F46,0xEF5311256AE4DC1A,0x8B0707D5887AE207,0xEEEFA1E5B9331AC7,0xB6CC32AC79EC797F,0x917AD124F107F6C1,0x4200A1D5D35BC9AB,0xC2F355ED80A393B5,0xFF3D09E8CD773C51,0x7B3D06EAC014FF69,0xC183D5423197C0CF,0x7F0CCEF4469D0972,0x198C32F76FBC1F8C,0x0FC2061D37B37E1D,0x474D89E54B880588,0x88422405C080424B,0xE0DB876F8CC41A0F,0xDEF74A4B9B91DC38,0x2D1EF0D8D8EC3398,0x0962FE7BF7AE88B6,0x43F4F0B2B9B897F3,0xA2054B343FA7BC7B,0x965BA156189FEEE7,0x0B706532CAEE7080,0x848DAE9B2CF7AB51,0x400ABECBBBE2F1D9,0xE5B9B9D2DBCFDCD2,0xA5DC2A923FDC4B26,0x790ED859126A1A97,0xB8FA026FC33B8219,0xE3BD4706E8423C81,0x051035E30C02933D,0xF8E5E97BCC031D41,0x6F41845F9AE025F4,0x3BE4BC005FDD3B86,0x2B111D12468D5B71,0x4CFFB5AA87930AC8,0x94E09E6C851E40E6,0x12E1D01EB0058E54,0xCA46B5E076DC795B,0x4F15AF3204C64035,0xEF364DCDEF2C33DB,0x9359E75677C6B58A,0xD08AB198840CC9AA,0x8FDBAF176A8D5CA3,0x565510B12EC62B8F,0xF9E6699D0D02DCD7,0x65B1862ABCAD178F,0x675E9C926B26624D,0x92432EDD8F2D7658,0x347C647B82424C5E,0x956EBA22F6E85F42,0xC6FD346A77024770,0x0D015B0AA23818F6,0x715B8FB4E83842E6,0xC318485ED45086D3,0xAB04524A1C33E8D5,0xC071D5D6C34048C9,0x4C1ACFDB8163BD7D,0x789C0F7EC4C2C495,0xC26936CD996C872B,0x918296EB6E53F700,0x99F926A1D7B475BF,0x227BCCA117D1AF1E,0xA5A13F4379C3E638,0x80F3D3A1B1AB2187,0xC5A144FA434B6E1F,0x8572A50693FF449C,0x6BF1C9AF2A42604F,0xBCA3B3973DF0E602,0x09CA486D533ADD41,0xC4C2791EC558874C,0x96C25754DC1B8061,0xC4AEFCAD03AC9A17,0x8444F7074CF6BEAD,0xC842C1DD6EB1B7C1,0xE8DBE2A5B4C9AEDA,0xA0C6A3042ED80505,0xC18EB868B14DCF84,0x72F7D722C7D468E3,0x7D1361B518D2A6E7,0x69F52C15AF6D8CEF,0x8732C44CAE1F8878,0x5FCF4EDA78A2AB09,0xA25373496F546657,0x97A3998068FE2FDE,0x009C9B2838FE2EE1,0x7B1A1AB940B59BBB,0x289116A25976001B,0x4E09934933B6064E,0x858F4790438B099B,0x23C583507065871F,0xA8CEBC8F4EEBC27A,0xF365659458F462A6,0x3549CDCA832916F1,0xAC7BB6E7A4912FFE,0x7674C7805D3634B5,0xBE95D7ABD857AFBA,0xDC042E6872C8C8A9,0x301381BB27C41E38,0x524E6E912D3973A7,0x94C7018AC5AD6BB7,0xF13C2AC4AD97D6AF,0xE7DFBE86446D9857,0xE78F0E519A93906A,0x12E01D80C511C085,0x812366F79AB902BE,0x0B450A986C30215C,0x11B09A7117C3448A,0xD6D4C08A6B935FC9,0x9134D3C15043F80F,0xE898057600A26257,0x96A9E11DE23E4AE3,0xB16949B5AF78CD96,0xA634AEB1DCA356DA,0x17F32E689F94E7B0,0xE668CD0660498E5B,0x4D246F2E518462C5,0x4BFAA02A51133CB1,0x4B92A13292C781E4,0xB1FE72ED5754FE96,0xE5D236B79456E9E2,0x05232A58893BA16C,0x9322504D467F4341,0x38300023A00415ED,0xD786D48756FA5E9C,0x327139D8CE4F9DC1,0x87E89521BF7AA93B,0x6172CFB50FCD058B,0xC02199EF1373979D,0x993B47069DA9E351,0xF7858A49F09C4D6E,0xA5B67F269287BEB6,0x26F8A6776390CC5A,0xFD5B1844B808DCB7,0x227E282241053503,0xA9A5DD9A0BD53491,0x255FDBCB5AF82D06,0x1CBC69955407D134,0x08969392F11DD1DB,0x1429936A1C5EE091,0x6633F01B74E43984,0x007CF3282D35179E,0x27D03AAFD130B62A,0xB7393208A17D74A9,0xE6C01041E6384645,0x6A65FE9AD8313990,0x4ACD4A0EC49D143C,0xFEB91A1A72DEE1FD,0xCDC50EB5220896D9,0xDBB5388234271422,0x840F14B702C7B761,0x0058567D903E7E01,0x05EFDFE1CC3410D1,0x28BE96F8F51F8AE7,0xB661F107043B30E6,0xCAFDB54FD58FD295,0x72695763B4DE0914,0xFD5D37C504C8086E,0xD56D67EAA8E27762,0x9BDEFFB5EA75BFED,0xB16524DB8634E8D9,0x069AB88DDF6FA74B,0xCC64F150A6FD63DA,0xEC142AA263D5E83D,0xCD5B7F13C616C5A1,0x61B7C822AFAB1FA8,0x65D09E7643A92A54,0x5E640E79ED6F5DDE,0x9F2F98A45F7D5BB9,0x3C0933ECD1DC6E7A,0xB60294E154B7332D,0xD4720888C706009B,0x6B5AABFC82974EDF,0x7F6914E2B4516637,0x82C0344D8934C90E,0xA0C121A68E15FA11,0x4CF0FBB83B6F8CC8,0x31F6A2364945E7B5,0x18C944C87CB0840C,0x5D4F2F99903028FE,0x2F634B0D0323077E,0x07409A6D1FB6BACC,0xA8A3BFCBF1566771,0xCA1BF0F7310B7D85,0x6B9F3949330690E1,0xEE69077699D74ED1,0x801551897ABA5FFF,0x2A123DEF55A21365,0x408D119A5A1E3DA7,0x5F269704BEE5DF5B,0x1C07A91C4F919497,0x5048DBB3E7CF6F7D,0x43E2C012EF63C5CD,0x8165466F8C95E414,0x055373F865430BAB,0x7FEB25EFBAF171EC,0xBEE5ED74A2A6617D,0x504F148D9660E69D,0xE27C1333C3A0E3F2,0xA3F8538406D454F8,0x385CC43033571723,0x801F8B830BD86830,0x3E9CFBFC8FEA79FE,0xF8DE794B429E9439,0xD041A208A416D722,0x60DBF202EF6C3042,0xE3B78DBDF5290F09,0x4CEDDCF6768FD9B4,0xBF5E3D0542F0D216,0x09648EEDDF53A129,0xAF4FE839D7B7A628,0x2B90806757DDC0CB,0x2810F72ECBB67728,0x443F38AF194F166B,0x7D3C1B8B3E376E23,0xE4828C8D5774A295,0x407931D5A885ECC7,0x4D94BF9401DE2578,0xFE956E9434097003,0x8772D453A949845C,0xF1BBA443B2316F25,0xEE55F6D4ED63837F,0xFE4C9DC797125CE9,0xC3812F2EC8F35703,0x2B6B893CC2ECF476,0x6D772B3FB40163E3,0xC9F8CA8BD486D9C8,0x513ABD24FBAF5DC5,0x0672684B5E76934F,0xB4A1045870966405,0x6D7A86CA3E63983D,0x76C848F73B06B529,0x36FB1D7DC5527258,0xE731C0681CA2AE8E,0xC45ADF477EFB84DE,0xC4607832425264EA,0x279B0FD0477EBA5C,0xE60A50A029196BE2,0x1ADACB61561158B6,0x85458FF7AC828ED9,0x38BC55B087C6BAC5,0xDFA855FFCB09C4E7,0x4620B37C3D6CE643,0xDDB65729A74724AE,0xAB640FB3D74DA0EF,0xA59AF7C7C7211899,0xC5444F6C09AD9751,0x4CA613D7EE5CDC50,0x7F01BD4351C5E6FC,0x37CC074B07B3C6B3,0x63A2EF1CCBF1491B,0x325D6F014C033161,0xDC04B5CF057F7B8B,0xD8F9D37B57B7F041,0x3A23A1683CE36016,0x6166F9F566CBACE5,0x9B9F01EA9DFD3F36,0xF401FFA40FAF565A,0x4532E4AAD99627D7,0x6881E325AEB2E808,0x32BB08C7A890A0E7,0xA8C05AF752B30CAB,0x24A9B176BBDC8EA6,0x800C3B39B94BCF52,0x21FB5DA52E097B24,0xE415287DC2F27BA3,0x20D398C5E06BABC4,0x51FED82F94705C45,0x8FCB97268F55215E,0x35F83B01353A021B,0xF672CDF1FF38C4CC,0x92058FCD7DBAB0DF,0xF54BDD0D31A7A665,0x4130FCC6655F777C,0x7A94081D0E3C4AE5,0x4BF86C366A678FEA,0xCD06953FC232B963,0xE5CC0D834C7479A8,0x792C3F089DDFD6AA,0xC11C1ABDC110B74F,0xD94E4B54B4B6D832,0xB807BC9A885627A7,0xC913A4E8792505B8,0x8323C093C23D9EAE,0x341F7D981808F54D,0x1FC627FA96AD15CC,0xD197D96D93A4F73B,0xDFF052CE6BBC1268,0x0A6C45224BB97E74,0xABC8ADF5BBC23D38,0xD9FACFEF75CEAC1E,0x9F152F4A3E85FF29,0x5FB2E171B1F545E2,0x3949E61070233488,0xC11A4D0E70ABE061,0x134113A1A0C48F69,0x03C1B2E1376A9C3B,0x6EE629AC43F17C22,0x5B2C57E744BB13FF,0x640C43EE4F1A32C3,0x3E18F7F1CBA5E92F,0x1BF9E5BF0E3442E9,0xCADFF63380E6F613,0x126E0C9261C1A557,0x3DF9E724A6C63FEB,0x1B0E6205C5BCE479,0x8A8590AD810E072F,0x6FC20808FAADA093,0x06705420C55EF708,0xA4C296DF7473ACF9,0x2A9FB8D1CD40217A,0x067A46D527E6EBB8,0x8B080634DF9C884C,0x0A7292E56F58E197,0x80FE6AA958BA348B,0x8058D07DC83A76DE,0x13631910F1BC7908,0x7025B38EF2B39C75,0x361F66D3C62249D5,0xC35A9267DC0E1B15,0xEB442C20530CEFE7,0xF1B5356A1074F94C,0x7CA57F54F26CB072,0x14E7F2E0D7766CCD,0xDC17E79317D1A754,0x822FB241F036189F,0x051173B0D42C2B9B,0x51454D00F6E5DF9A,0x0E87164B507F2A9C,0x413CFA6EA2373899,0xF83F5EEAEEA34F40,0xF58A707DF2EDF1E4,0xF6D4ADCE902DE04B,0xC21DC29A59587C46,0x5020B3E278AEA0D9,0x0A8D32C646EB2E6F,0x4660B3EF43318C12,0xFFEBBF482D628D3F,0x5FA0E591673B7B52,0x3F0740CDAC379008,0xEE2D57F9B536F25B,0x4359A103266DF41E,0x590E1F8731F97148,0x9A2DE01E2DA482E9,0x3B189706E95688C2,0x56537C6BBE5DE0A9,0xA0D4F765936F93D1,0xFAB262A8EE446CA7,0x35EE22AC90E143D3,0x37E9F66577D5A636,0xC4FA02DF670F00C1,0x7810653D7760DABE,0xCE4C09A98A786219,0x995A8331E2F6C224,0x9549DB8275EE725E,0xF13B8841064C3738,0x192AD45B2EAB803A,0x8D0DD25A689D56C4,0xE72074AE3F61D68D,0x485DDFFC2B715F45,0x06763EBD99F04E01,0x8D5296C8C8287012,0x16720CBB732674BB,0xCB84B31CEDEBB1A1,0xEF1CE17BEFFE4881,0x9FA25FBB58A073C1,0x068FA256F57603AE,0xB2343DAE71BFF324,0x9E35D95EA4480F16,0xF7A44ECED5301AC0,0xCD83948D2CC1ABA4,0x7DC3F7BD1FDBF6C7,0x8BC469D80447F487,0x814A372B2E1C8E9C,0xA31B34BB5B464663,0xBCA413DC18747F43,0x2A4B52A8A34DBCD7,0x3F47228626C22C75,0xAE28734326C03BD0,0xC1BF06B1F3A90E65,0xE8513375A44D0552,0x0A3F088B162FC59E,0xA22BE4D294AFBD8D,0x7413AD6E257D8FD4,0xB23A1C7CAF463FDD,0x4CBE36AAED252288,0x587A58281E2481C8,0xD6209A63F7D72481,0x5E609D4712281250,0xB06045FFC77AE29B,0x799E7B7D95C3E7B0,0xCA22B1C40A1EFD6F,0x9D71536B4FAAF2B7,0x2B7F3ECCFAC0C4B5,0x651DB616D0ACFF6C,0x2A441B83DC730D81,0x2C2D94CD0A980581,0xC31D2647EA23AB22,0x42C94834B3831282,0x0B421DC3F62EB318,0x03C50F4366827357,0x829A86597FC09391,0xF372EFBAA0A95FFF,0x91BDB28D2460A93D,0xE54BB6EC3B3315FF,0xC7C2B08F40DFE20B,0xC27774B69A8E3994,0x382EB744A0407015,0x56EB8B597D945CF1,0x47F4DBE4C9EDB798,0x9831A42A3CC1BD62,0xC2EE63EA696B85FB,0x0A1EB3E182446C4E,0xEBB9EC4086A807EE,0x4192A64D5F834E56,0x10CE35EBB2F3CB7D,0xF020BCAAB0D977AD,0xF269E82639D45ECB,0xEAB8B5187F421568,0x90477DDE46CBFC23,0xE12B8861D1712858,0x6B8DF1C3AEDA3455,0xC58153056B384FA6,0x4F4C3FE034B1F7AA,0xF6675B78C7D40268,0xC10E198C0A276126,0x83CE1E09F3B09969,0xDA2D40FD62B4A1F6,0xB0F53AF52FD67DB8,0xFDDE04B68B0F0352,0x41F5276C0B58D159,0x62E7C32AE0166551,0xBC2910CD7472ECB6,0x57554E874E119EF4,0x59F765D89AE69806,0x10758441BB8C0B00,0xE7D9A0F02D85C6A4,0xF23B37C8F8BAC3D0,0x00AD36C5260E739D,0x2060AE4B802A907E,0xDB262AA0030CD7E5,0x668DCAE3D076B439,0xD71B3373099382F4,0x6A8E6C636169D499,0xCA90F6E49CD1F115,0x6E5AA4748C689273,0x8EDA16C49E819AF1,0x954FEFCCC7D43AFB,0xE08775CD18178E75,0x3316BF5C7299A5B9,0xD54D624D6D368B5D,0xF884975B98A31C68,0x9AA28F90CCD082A0,0xA25163CFDD1438FF,0xC37FF29C7B9081C4,0xAF5D54472EC6CE96,0x9B995427B6E92A55,0x20F8BCC9FAC47212,0x2D3F6B4602DBC45D,0xBFCBE72800E19448,0x8D5635012F3AE229,0x6782323BF547D253,0x806386847E892CB4,0xBCB78BC3F6D570E7,0x4F640807DCDEE8B0,0x970E48B0C2326CB3,0x55CED2178DBF0D4B,0x8325DB4FE7E65C0A,0x7DEC286E64A47801,0x4195950CAA8FBF8B,0xA223192FB08EB1C7,0xA4D4B86BD8EB4C52,0xF650E7BC8E7BED39,0x87071AC405609400,0x17E0235BB1F095B9,0x03DED2A573B08B6D,0x7D09EDC7730F7CC2,0x2E08246821B35C41,0x1C03581C695B42FA,0xDDF7176D89F0510C,0x99127CEE91D4797C,0x3E39374FCE8B6693,0xAE1387C511FD59B5,0x3F9252F5B312A650,0x8C163499C224765F,0xF009E728E62A76F1,0xF1D7DFEFA9A4DD41,0xAFFDA8C90AF77FF2,0x02187705BEF59347,0x7774D7C672E768DA,0x152C9278AC982534,0x09F8F51A80A15587,0x2C5AFD0E132F8253,0xF97B95E94FF1DCB2,0x0D8B1DDF7CE34E3F,0x9E0F07B19C2B5D51,0xFD903D05C0A98DAD,0xECFB8C27A60C47C2,0x84BCA1D0EE10C496,0xF5FB21A3EA808A69,0xB91AF98105AA1EA2,0x63F0765E2D6B8307,0x5072D4C9879DC36A,0xC4FA4AA570F42F7C,0x6F5FF498837987C1,0xEAFFF7598BC7F1ED,0x89D4B432565FDEE6,0x51D161C08DF1B91D,0x360DD481CB857D93,0x8E407275FA069532,0x6460BDF17F7006C2,0x893AC9667EEC8DFE,0xA48CEF99BF51187C,0x5F205269D423753B,0x1A09EDDB371C3878,0x0D207243EE4775F7,0x12315584C4B0B023,0x65FD6BB99E0EB131,0x250E2E0D29073D54,0xF17AD0AB86C65A06,0x0BBA43E58D4D43B0,0x50972FF62E1E21D1,0x7534D5E79366A3FB,0xBAA278F6B54597EA,0x3D7A9938D8DCC581,0x2A1832F3B0EA9363,0x5619940AF3B63D6D,0xC659F5077F5F152C,0xB3D55A8B8644EC6C,0xBCD3208A04F74A00,0xDEC7DF835C64C54B,0x9982EBE653E9DD17,0x201A2F2F87B92FE8,0x9AE632931A7197A8,0xE69F164CD1DF2C1A,0x1EA90D43710A47B8,0x5F8E13649E94D51F,0x5B8121C1479E6B4F,0xD7694AA4C0028C07,0xB405C33E3A132CF9,0x4C0371970DA4BA17,0x11A74DB1D9B49FC3,0xE5A0F5F340B9B999,0xF0A67CEE8E0B4B08,0xFDCF7B6E863A1A64,0xE701C841DD17E80C,0xB127C2C381E45312,0x99FCCD3955BAAE9A,0xAD027F18CB70DBF0,0x9EC8EB829251FC59,0x27EA7A55B2C694BE,0xE007085480DD412E,0x881A9F84844E67D4,0x95EEA115BB9227BF,0x1F6A4423A23E5C69,0xDD7F987D765301D3,0xF8D14C8004B34E78,0x415CD07FBDBE6BFC,0x846C60FFA1CBB6AD,0x90B6AC76BA4A23EB,0xE43ECE9F93503EB9,0xD0482350DF43D7E4,0x97CA872950EE0416,0x9B0E44974D0B8338,0x2C160397D33E7F2B,0x73C52832821728D6,0x5BFBA5E9E4936E75,0x692E0B31B5CA0460,0x1E526E27B79DD9C9,0xDB5349EAF494F6AF,0x9BEDA3C3FEE88E16,0x31813F87E4ACBB87,0xE57DEC54E2EBDF40,0xCF8BF988E58075B4,0xF441A2E6BF3D57C6,0xEF6F85E7117996C3,0x629F1D7365B7505C,0x605B8CF95A6069AE,0xAA8F750BDC3F9AFE,0x0CDD52816833DD3D,0x6619876DA1E0EECE,0xD52F0AA23B0D1C85,0xD4519EB3E8DAC2CD,0xBB431375911A7BE3,0xA3688B83823BD017,0xE96DE596BCA96E6D,0xD781235978E1F0AE,0x9939720C02E0C79B,0x68ED7DBC502BBEFA,0x86D39E1EAEE3ACF5,0x55E34F596F1360B2,0xE679B98754BEDABF,0x413C9AFD7F7675F1,0x9923218916CBC023,0x95FB8262B6CB18F9,0xF69F581F9216B3E9,0x115E5D0ABA7AE1DB,0x5CBD3DBDC5954EBE,0xBA7B0D1657D5F58B,0xEBCF8196877CCACF,0x8F223EBDB5033F85,0xF666ECF706DB4FD3,0xD76732B24B3E5461,0x3AB87F539F094155,0x6A7CC2ED48620359,0x7CE9621E8281B640,0x1C0C28F1DABC40D8,0x4F498AB8A7A29384,0x5790997102921DBB,0xD81E15FD2423EEF3,0x3C7B025438468773,0x8215543D77F689D5,0x5FA6A7C4DF87165E,0xAB344C83F0E3BD03,0x12395147707068E0,0x84E4FE1E56BCD62A,0x869AFF3C5BE3CB3E,0x4B213780DD7C0A68,0x5FFB656D66E884F5,0x977A4DDFD0AF50C0,0x515F0B7505C94236,0x83FE5B8CF21342D9,0xB5447C6EFD69645D,0xBA96838505C26FD4,0x72EEA2A9B3CF42F5,0x5A45C0503FAA0F1A,0x981B989FEA137EFB,0xA4E229FC6806F41A,0xC88C4B80821231F0,0xD48A8F0D747D9A11,0xC8A6D20EB966996C,0xB9432ABC231F217A,0xE9A38B7869E70497,0x3425879616AF604D,0x7422B95E58E9D65E,0xA46E6F8AD3E4FBA5,0xAC880210EDA075AF,0x13B747BEF70BC0E9,0xB1F00B59D4D27CD1,0x9C9D512D6D3A1115,0xC154B076D3427590,0xD9D124BBB2173278,0xF3A011B3E4D088E9,0x9A2092F3708B191B,0xEE61C506FEDA2421,0x6B6D0C19B6C5EAE7,0x94CF4AD982DC5456,0x4631119AECF7E9F7,0x48DB469E7105C85B,0x2F556B8F5152DD4C,0xE7F06D59B560646D,0x47BA0C5DD1201C2A,0x576FB16F27A8B8B1,0xC6C01070A5073573,0xDFD4D53B7A2EF9B3,0xD3484B174CD908D7,0x5542D8189C29D33E,0xC0A911CAF3978E4A,0xEF418F54FA078C2E,0xFA23EBFC211BF857,0xFAF103C5B56CC8E6,0x0E2BEC8B2FAAE1C1,0x213ED84E317CB1A9,0x45F96DEDC0B3CA66,0xD82720591D4E4DE9,0x3C795233C59F7A97,0x59EB79EB0011FFAA,0xFF01F059CC361569,0x6342D2415179931F,0x494E382B9BFE80DA,0x91A153AD389FE5D3,0xA2980536FB691FF6,0xEB346A89F8671B8A,0x4D9A4F230E6D295B,0xFD73878B343C2211,0xA53C44355289E913,0x16101CC3A8C89AA5,0x3B071BAA554B9B5D,0xDA0E82307E0FAAAB,0x905E8C4FA7865FF1,0x991270EA87051E0D,0x3D3A846EA929BE47,0x36CABBBAEA0D8788,0x6523CCD1EBEE00E5,0x0C393904E9E79306,0x1C23BA3AAEF91178,0x9BDA232578157857,0x6496D7269C2DF741,0x45E1B78E782FBCA8,0xBB616258FD42D49A,0x557112343A06AA33,0xCF8636B8ECD11A49,0x501D382935FAF111,0x8ECBF9DF448A6DA6,0x13451145DB121E2A,0x5E8E64B254C0A3D9,0x6E593843A955EB07,0x92B7A0792525C9E7,0x58DF06974A6BF7B3,0x729508438855193E,0x83C9499853ECB4A8,0x72B7870C2E8645F7,0x1C076A9159596524,0xDD32A90FB5E35BC1,0x859ABADD24288A33,0x4B078D2EA1231C76,0x727494CBB1DACA52,0xF3203CD7002A0DD8,0xDD78B0AC34964FE0,0xD7EDD303FA61CD96,0xB568C5B84A794205,0xB13248CA484DEE88,0x3284DB096A0BF942,0xEB62C9536135E464,0x40013C84E2D02CCD,0x889A881058A3D90A,0x642A849571BAEE1E,0x6AA0864AA47E653E,0x721E311CCCE5F020,0x84A99CA77C4267CC,0x657FCEB382A17366,0x48DBD26914EDB1C1,0xC61532E2D64C1263,0xF8D6093D578ACB4F,0x733935159FC43B12,0xE9E7168E278C6CD9,0xF3CE31954F1BAD9E,0xFE50B664DD96A593,0x9BC18366C1419250,0x056C004B420B7811,0x1518A918BE194FD0,0x75DDF722F8C6B022,0x39071AB5C3DEA7C8,0x6F3CC6C91B572FEE,0xB1AF37228FFFF938,0x7CCBDEF040B878A4,0x070766293781E2CF,0xCD9E6DBC8D1FB575,0x8F11942EAD676FC9,0x0DD984CD5F4EB6E5,0x4814E18A855C14DF,0x5EA45F9932A23B52,0x1606B564745E5EE4,0x1DAAB09EE50B9B32,0x346508EFB03B3F77,0x84D6504F4C8588BF,0x9738EA6A4CC2E868,0xCAE3664A8B22B0FA,0xABF488C90A0CC20C,0x86FB33E46BD0A1F0,0x91EF0DAD60AC04EA,0xC341DFA2B86AB7DD,0x14A4E0097AEB50B3,0xA1E1A001056040C0,0x5B53AA59F79882A4,0xF3131E533BAA841C,0xC66B98CAA7B84852,0x7BF00CE2F5460975,0x8814DE6ACD968948,0xD9D3C115C8E3C8A6,0xCE57FF24487041F6,0x96332135DB2BAEFC,0x43AF81FF4AC06076,0xFAE1262429B98A4C,0xC2AAFFCC25B7B293,0x34C5C9D414C1CD52,0x651153FBF7C67E51,0xCF74305FB75CB4A3,0x521B2F8049937686,0xC5964F0D0FD8E3F8,0x1F2409696322BF7E,0x8B6B818D56124084,0xB5F4224BD334F4B9,0xFDC02EA465C75142,0xE86A5306C90ACBF5,0x718C8EE41BFA366A,0x0C70E636641930CC,0x5FC87BCDE524FC34,0xA2A172B7E5A3ADE4,0x5E06E356B0209DD9,0x9C06D663B02C25B0,0xF23507A2D1E91DD3,0x5DD7AC2CF9F553C9,0x15A5F53A9D1826CB,0x435624640F77FF1D,0x993634BBC5379127,0x58C70BBCDB8D3428,0xFC86A6F356B31E20,0xA4DB05B9CC089B84,0x597219E7E9529E98,0x6640381D6A0FBBFC,0xD2A6AAE578B717F4,0x1CD36042F0405A00,0x1C0CA8BBA37CE942,0xE2CBD9CFFD8B26E2,0xFF134F0A4BED7FB6,0x9AA1DA4E02E3E0DE,0xE3187D95BCF2FD90,0xE34A84155DF7B97C,0xE59E7FC541230BF1,0x3B70014E429EFC76,0x040DA2DF3D23795D,0x26974C9E8652BF6D,0xE5AC09E308431A86,0xA8E181FA96203D46,0xE2CE5E2FD4E72E27,0xD826791E528B41B5,0x6F66802161B3C6D7,0x0766A05B94D2EDEC,0x98CC9B27B4C598D3,0xD84CA3BC14FD6459,0xD8AA0F5DDC5A6193,0xDB31D250DE88123B,0x0DC7C99C74FC05EA,0x2CC4AC873F116506,0x9DBC8242D952B621,0xF898EEB7EB023FFF,0x421BFCD7046DF270,0xE29193B8D8A39C51,0x40EC3117FF0BC0EB,0xA1ABAA9975388E59,0xF13C1BA2F2CCE5A9,0xAB82A4DF3036BC2B,0x4965EB921FF62F15,0xF9AD2C5AAD9A3708,0x5E1B0AAC61C878CA,0x41287AAF62232C99,0xEB0FD22617EE8C1F,0x8B2F1529D4B5876B,0xC2B0B74EB6E329E5,0x969DCBF834BDBFCE,0x21D56D71677A5177,0xCA9D7316C15E7E64,0xB5D49EBC25F9D9EA,0xDCE2E68EF1AE8E79,0x5A92111A4EFA4777,0x4EC1B94232BC9C6C,0x26694B180BAB9879,0x3596FBCF082AD6D6,0x769168A33107596B,0xFABD66EC729E9D92,0xFCD2912C80DDDA9D,0x4D3A38ED32BB6E32,0x722ED6DAA52E7B06,0x6EFA57FD71CB8A97,0x8F4D41AD9AC39715,0x9899267A1FEEB9B7,0x39E4D42128C8D57D,0x17243074FE8BDFD4,0xCDDA3CE0C3902460,0xB710B2C292FEAC20,0x0504A8383D125091,0x93D087B50B699082,0x7DAF3D20A49F2EEA,0x1DF9EADAA871DFCC,0x51CC05B4E5C3BF08,0x283A853CA70E5412,0xC4D852E54CD35AC1,0xFFD9C1DF84FAEFD3,0x465DA89AB6E953D1,0x44E781C4A7C798CC,0x175A0BD92A30A09F,0x618C16EE497DCD2C,0x2347F8CC77FD40A3,0x392C7B2E45534BDD,0x317C60152047DB84,0xC52B3A9E49EEA4A6,0x4BB14E56C79D6BB7,0xD57194B26B64A130,0xC761A972A2297E0A,0x6C66AB3E9B4C39D9,0x01F8C7D9653AF844,0x3CEAF937848A8C23,0x3FF70F172F08E644,0x973E56375CC98D3C,0x76F5BD7A464BE41E,0xBCC87717E51DB385,0xD3FFDB45A52146DE,0xF4310384190E9EDA,0x56DD067FD31AC7F6,0x34CC381371DFDFB1,0x5F1B2D3CBB117A65,0x9AC250EC4BEC8BFE,0xBD182DA96B1959F6,0xE3AA58E7A772A44B,0xBD0D312494E6F633,0x89ED794C941B4145,0xFDD1DA310AD74ADC,0x1B47BD74C37FBDF8,0x769387261ADE8A49,0xEF38CD69A5AD5DA9,0x888B0D04E245D601,0xB34C9D1590DD28F5,0xF837702D4CF52B3D,0x471215367CA92F89,0x575D94682DB1ECCA,0x816426CD00D2E0F4,0xEF7BA15E8C48C494,0x20709212C6722A73,0xDB0486720A305B93,0xE58EA0FDA0A03E80,0x8C91DE1B98FCB0C1,0x9CF872EE6D719279,0x46179FAB653C89A5,0x1B898476D3427B34,0xCA26886415DF5147,0x0304C9ED2C22893A,0x99FF4ACC962BFB31,0xED4D65DF19341A56,0xE875401B67E84846,0x4A80BECB48E69BAD,0xC1182FF84411220C,0xF84D58B5B1DC499E,0xEFCEAF15E9CF7BCB,0x649EBC62A48FFC89,0xD5330C545B7150EA,0x285FEBD06C09E6C6,0xA99C2FE648A352A9,0x4752B64A56BCD81B,0x63D78942DB9A6BA6,0x120B78587AA1ADE7,0x934DDBEE9F5A88F8,0xAB22E830475BDB79,0x018A76CB904CC646,0xEE06DDA97C20D610,0x085B8CEB629215E1,0xB28F83A30A3D933A,0x521C345FC91E9C2A,0xEFB946A0EA767099,0x3C4324B523D7F934,0xC07DF652589EB63B,0x3BE65B53200F3AB4,0x03D446390CF5335E,0xB0F63C245E9A8CDE,0xB8E107C076C7946E,0x3E26DE168501436F,0x82D34DA063CC0FFC,0x61E071A3CEF99D1E,0xAD82FC1DFFE15867,0x001B2F105D54BEA6,0x05E4C05E1FEED754,0x62F8B4763AAB8E8A,0xC8FB214AF671F7F7,0x56BD9E2DDC4246DB,0x4F00D4E6CA1A9004,0x1630082BD6AF23E7,0x73D431C29ADED4CB,0x927646EBCCF0D238,0xBD3D9BFC6DFF8282,0xA07D23A08578F606,0x9325B9CD9C9364FF,0xF2CAB6CF1C2C7655,0xD95BAC933317E2C3,0x39B117E4EFA652B2,0x9451088EE7449778,0xC914AB302D4BBA7E,0xC1030C5ECCC71BF2,0x86F02100B6FB6E9E,0x53C0B6D170FF9A82,0x0F2FDCC215A8EF3A,0xF461635ABF8B08A0,0x233DA4B85337D498,0x5B059990D828108B,0xEF70456B1D5A1FBE,0xE724EAF1CE727302,0xDA852FA3F5415D28,0xF3A1B0BBA7601E14,0xD2964F745D884759,0xDA5FF74574A1F5B3,0x164F3835860FA347,0xCE938259E604C593,0x1D4A5A4DC3000E37,0x57C7525C216EB50E,0xF73F628AC6CE90B9,0x4DB0719E39EFE79B,0xD345FAD94033B540,0xE24A29908DD3AC68,0x4ACCEA0E2D68A56F,0x4A0137E820E03F5D,0x3FED9F1789CEB654,0xA1C9ACB60650A02C,0x1E22B8D21D844A98,0xC674478367A4038C,0x75A451B3AF24BA57,0x53B3D3E9816C3A8D,0xCCA4F164357D69A9,0x2A21EB74C8CA876D,0xA5207AD27E1FA962,0x2ADBD0A73D44807C,0xFEAC317B1A3F5E99,0x76BD6839FA96A20F,0x31D69FB93E2C292E,0xFFE108C3032DA981,0xD3D3624C01B6EDB3,0x4AF8D0BC9AF22754,0xE7EBD2EB2C76C9E1,0xF0B0C1A970568215,0xE8D97B5EA5A177C4,0x711EED767E926954,0x75BE206D4D165DA7,0x71D6A917EB4C8C9A,0xC282590159711684,0xFB7055F662272D93,0x62337F7CF2999CBA,0x74955CFA86E9B030,0x6A9EF3865B4E56F8,0x3D8D3942999CE729,0xA9175FDD5572A866,0xDDFCEAFDBF5BC3F1,0x256A2D892253A822,0x866E4219F3AA4F46,0x280DEC8363A1D01D,0x34949619D2BA175E,0x85FBE9AC23EB8BEF,0x86255A3870556BB5,0x22B265CE7C24D31F,0xDFB0DE944EAC373C,0xF015E1B49A91C313,0xF2F483F8FB549E93,0x0820625085418A6F,0xAF1ED0761D809C99,0x1372C7A635799FD6,0x435860E4C2F34FBE,0x5E4B2F0DE4097C24,0x427941A7798C0B1A,0xB707611B21D18015,0xE2F2CB557AB5F26B,0xCA2AB35F6D94D438,0xD68352B3069CA52A,0xFF9C0FBF41806B0A,0x31B65E139C1119A3,0xFA4E5D8F56FD288D,0x1056609BDE70840C,0x21C5F7C4ACB52BBD,0xF3E4BE2A47286B71,0xBD93E79E3EEB8D31,0x3330F71D42401BA8,0x921F42EBEBE0957F,0xF775C55C7F62FD79,0xD28D030AF3985667,0x41347853BA573F8A,0xBB9986321628ACC7,0x56EA4B8C5AC3BC38,0x9B05531399001AA2,0x57ABDB939E81A362,0x0C9C8368C307F14B,0xC7D3ABC37A66E93D,0x89340BB192960896,0x3BEC937C1EEB4A1B,0xF9783683212D6474,0xEF28C897009612E5,0xA982A1EEF13534AF,0x7DCEF68793D801D9,0xD3191D78D358ED59,0x0D600BCDD39AA1A9,0xFBC176D1EE052397,0x0B5C394DF32FB055,0xDF811145C1B6D657,0x67D327C152B7ABF8,0x6D1F73AAA8B94B31,0x89E6E252FB880D81,0xDF6541BB1F41D4DA,0x736DC2C3F9D1A3EC,0x23C771D8D7C9FCA7,0x303B45597148D829,0x380CCE7367749C42,0x1FCC0FD7E0BF9B4D,0x2551F14F849BD19C,0x2636F2EBD7C601F7,0x4552C5C091F56F89,0xBA98BED6B3B6AEE3,0xF1BE7A635DDEE2AA,0xE9CB3F34359FCAAB,0xB1926F9B8E893F71,0x7E44B1097A1F2037,0xB8D00F6D8FCB825C,0xBDCC799B0C793795,0x613C7FA023FFCA41,0xF5AF73CF92547440,0xA1CE7912A7668543,0x416B0B16B9DEAAB5,0x77D028300B87E921,0x1AFDDBF95DD34FC9,0xC4DC17D422C19D72,0x757F37BFC34DE6B9,0x5A3DF5F422FD0A21,0x543ECA755C3EE7B6,0x48CC7584E0CE9C06,0xE934030F506F55A8,0xC25D17372945BA53,0x47AFFBEFBAD9DFAE,0xDF108FDA029E2FBF,0x64B95086EB50C893,0x25FFF246401E9F58,0x7D2BE0826DE4259D,0x34E7A35FF0FB39AB,0xB6910650BC00053E,0x47EDDC53D322AB6C,0x387F5249171291B7,0x887FAE777206B450,0xE21848DF20D079F4,0x16C46864D53D718E,0xEA39A1E911D5CA48,0xBC9EE9F167046271,0xD176650C5C75ECED,0xE92008109F9835FA,0x2B9EAA32D7C3E9D5,0xC5CD3DC459135474,0x6B3F6946FF7A406A,0x3C69550C3798D395,0xDE429124898668F4,0x547DF9CCFFF5810F,0xDB984C9EA5A5598D,0x8B58BFFBCD01668D,0xE1218FBE94AF2A3F,0x0306AAAE4F3A98EC,0xAFBBEAD12176154B,0xE1A771FBC5364355,0x679C4F8F38822D9E,0xC5E0A1476FC1E01A,0x85932324AE3E66DC,0xF2851DC061C93859,0x1632463348C94175,0xA940A15106F61E2D,0x6A914B2EE8666FD3,0x28202DC555FFC18F,0x02F263C303AA55B0,0x2800C208F5CF92C0,0x0856BEB0ADE3D707,0xA2CC7C3FF1074295,0x0D4E3051B97A0931,0xF5800B796FA124A6,0xFE453E47B7FFA61B,0xF1F7800341185C71,0x8FC8549B3DB069AD,0x30C6116CB44A1EF9,0xDB5C786B1F53EB89,0x12F37BDB5BE66E28,0xD7226769C79BC650,0x99B8B27E804949CB,0xB4180FFEECCA752B,0xA03D140E8613EA5E,0x12608A02041E430A,0x15F7FA8E13D565F7,0x8BDAD79110EE1EC0,0x1595EF0AFFDEACAE,0x6E246D3E43B24B5A,0x8BCF469CD663553A,0x97987270C5300263,0x54493EB09F7FDD74,0xB920AA705F974CD5,0xFB662CCD1C952989,0xB3D5117A9499D26A,0xD8D493D671DACE85,0x498B37B8B825323D,0xE2BA70AE406FD891,0x1B76BC387E18A4C4,0xBA88449C02356550,0xFB0E1C15EE52FA74,0x672ABA63FEC90D01,0xFBBD3B329BE4C802,0x784C5FABFA56986F,0xC40D6DEBB057E7AB,0x8151B246183A21D1,0xBB90CFE65D384B98,0x3A05F0C9C662399B,0x4ABAF2D4FEC5FF0A,0x4775B08BC6E74E27,0x6A408AC06485470D,0xB670BDE87ADB2D1D,0x9D7D1ACAE03B89AE,0xCA3BD76D8597C70D,0x5CE8A1AC94D8A450,0xBB33F058DE2DB18A,0x7AAF68E5794B3206,0x51B98A12B5462390,0x78992C38A6B26A98,0x044AF41794C15D6A,0xECB1D2347785C3D3,0xC1EBFF6199365B97,0xAA1D56E9C572E6B8,0x319B291737DF8F30,0x1303541E7F878F0B,0x17ED63E2BD854EFC,0x9D05EA42DF7160E4,0x82037487B68A4E67,0x471A6F4030E9D0AF,0x4578C2C87E4EBA50,0x7F36D8B5740D1734,0x9AB99755DABEA61C,0x8FFB1DA306F74155,0xF6C94B56BB045997,0x8872E689DB0B199F,0x0092360A0A14EC41,0xBB178CEF7F7EB90B,0x7052AA753BA8F956,0x30259ABC49B93B5F,0xB852F51E7860492A,0xC702BE1A607F6D74,0x5B9A514EFEE5D186,0x2D6FA1FFDEB6E618,0x1848F4409983DEB6,0xD6E6EF9FC2A9C6FD,0xDCCC601BF9F8236D,0xDF843DF02C734E79,0x700D6448251FA015,0x816DB3954D278446,0xF479294A4D8D2805,0x07AC98B2BB05494B,0xAF7B7107004D233C,0xD5D59D577768C49C,0x9A0D7848BA174584,0xD8B2F1502CCCFBD2,0xF9259C23113890FB,0x4AA4FFA34911B019,0x95B9166ED647CADA,0x55795225948639BD,0xA5F6EC3BDEE42FEC,0x85F6FB61F835A088,0xB87D8D8072980315,0xFA6E62425F176CBC,0x00F5AB91FB023738,0x4FB2952CC08CE310,0x5A1B9C06B25D1E1E,0xBE40390F2845B318,0xBC53C7CA244757C9,0x05D6C25BD5FFF1C5,0xA54291DC684D15F6,0x4E6C73C78E0FDB2D,0x63111F94C777FF79,0xCC416E74B16149E3,0xEE26313FF28F0A60,0xD654F614668D2F96,0x72F1275B6296EC90,0xA2401BBEC62246E9,0x7F955F99322B01C8,0xA841A809A6BB1732,0x6BF1C5E3C426148C,0x0B5BA1340484D7EF,0xDD6FF44A1CC46D24,0x5DEDB7790B80C7B2,0x1C25D423E6B32DC2,0x6FD3EB7AE5F9DC55,0x522DACF7C56E20FA,0x1A420F4AD3316C93,0x7F1D7CC0F2A6FF76,0x3DE45C99189CBE06,0x1B3A270633E72590,0x5934C1E9884A5AB4,0xE50440E64B4932C2,0xFC4B48A7FA335F72,0x42FF1C27C79E257A,0x9A52D73E2032B4D0,0xB16CFCC6C87151CE,0x2E3E04C24A1B479D,0x63BE42E3C17CC03B,0x2BDDFF6670291240,0xA99EEB80220D64D5,0xF077A057B3C82AAC,0x9CB4D301B8417169,0x96526046217A0031,0xCB2612F4AD82ADB1,0x0E13322CA77DA63B,0xD84C30F4C5D0832C,0x0D46AD803E7A5511,0x4FCED8173FA1273C,0x883029F92C21C479,0xFE118AC234CA9CFE,0x12909DD2F654754F,0x281D135D62CE7D29,0x4928540B19500E5A,0xC5BDAAB3039280EB,0xE9C2DCE92D531CEF,0xAC1B86E329263446,0x55B9C86F3BFE66F5,0x262A294393E07637,0xB9610EFD8BBA8233,0x62E0E9BEF3B898BC,0x499AD89E249FD384,0xB5149B6759D80A0B,0xFE0696D56E36D2A5,0xF37DD5FBEE2EBA68,0xA5EBE0911FEF2F61,0x074122183664AD73,0x7A765B1274060310,0x59222EA4D5870735,0x1327D362FD0EBCBA,0xD17A0B50ECBBB13E,0x8223124323EE2641,0xE7794A89FDF079D7,0x6B5FB121EDEC70BD,0xCD6A5808D90FB8CF,0xF3879EFCFECB4D71,0xEB8B2DEBDCB0E262,0x1154C33B10654B15,0x949A8A747E7BAAB7,0x70D79F1FB7E2D973,0x62B6D657CC0FCBCA,0xC0B1812CACFCA59E,0x303148697ABD2A2E,0x36C19C51809F5BB4,0xC16B0F2723E1A7E5,0x69CB57437FC09DAA,0x5C6CB5BE5F97066B,0x91068963A8CDC7E0,0x807E4F3D732F9E33,0x3D6CDCDC8233F37D,0x842E15F35BB1C645,0xE702D0D87E2F446A,0xDF5BA791508764CA,0x983FAA7211A974C0,0xE2FB5EAA8A3EF162,0x57C43955ED9A5F7D,0x06B9AA216D00EEFC,0x69015042B950CA5C,0xBC214D0E6DFD0736,0x095C6D7951B122C6,0x5E9AB08BF78AE33A,0x50E9AFC5893AC720,0x752604A08D84831E,0x37C8E0816240E3A2,0x86084F8C2EE5E2DE,0x96CDAD63BBE0524D,0xF03B2BED501D955C,0x6A896CE88EFA09C3,0x30971654E47E6C11,0xAF0A7E8774A13D82,0x0AD0DECD13351D3F,0xB3D46DF106E69A64,0x7656DFCBBEF888CD,0x5B68355001BAB160,0x5372060647042A9F,0x2F93EC7BC2F79BDC,0x6A0EBF90B45B4A0C,0xD6A7B96EB61C038E,0x29F5C2475CC07CA1,0x34232EED73EF9264,0xB476853D12D381AC,0xA50FC9CA2596CF23,0x21CAC5EC36696CBE,0x71F7B4844343C06A,0xAC938419F826C106,0x187E0C1B8712E87B,0xF3BF66C58F6C47B5,0x2D8314EFF1DE143C,0x6F63165AED7FE433,0x111DE54119EF85B5,0x5A8756C74447575D,0x3A761ECA2CD67D1D,0x4915975E9DB76062,0x086E2C5D969794B5,0x7E0428C9483A2DE0,0x469F062A053BCF98,0x3FC4729C764D4364,0xE8FC9E00D350CEF3,0xE1064B95D47CB03A,0x052E0189C8CA50A3,0xA4C271A9ABC6FE94,0x59A8F4DC75786432,0x89649605AD828311,0x56E12F8402215714,0x06BCE53D9F28B12E,0x3F5416EA4ECFA4D2,0xE4DB7CFDF92D78C3,0x6C26F0BBA605A3C1,0x2A00548A2721BB22,0xE993E01E21E947BF,0x69D3131D07222645,0x2393F26EB2732903,0x276829B009AF6B6A,0xC72B2A3C017349ED,0x399FBFBB5F218B28,0x75A1569DB2653A8C,0x72EA5A73D340D8DC,0x29C9A95CD2F463D2,0x7AE55099A29759E2,0x19FDB164E6046C81,0x15FC227CC8C362BB,0x31E15B0183BE2478,0x38B07D3B9CD463DE,0x770127A27C9D3A57,0xC7CE64D97236B4F0,0xE8DA6A25EDEA6595,0x42E9FFB180EAA8B8,0x37B6381B291F0F34,0xBEEAB2139935C7F4,0xCC21DC88B9BA5FE5,0x44D203E011779E60,0x68C575312FAD436B,0xC32F029E21BE547B,0x0161045F34CB787B,0xF2BF8EB6F1B51544,0xA715AD83934BCDE3,0xDBF6EE039930E152,0x2CE629B5D1E968B0,0x5FAE401AA0A33328,0xF04459F9BFF18265,0xBBE264AFA4C39ED2,0x54DCE01005F1F79F,0x45BD756B06095E50,0x3C14F2E14627A0B0,0x9A8E2AB0AE6655E3,0xDB637CFD1755939F,0x6163CDD8B6F4FF2D,0xCD640AA6700FD314,0x044082372224063C,0xCB24D4E6723B5C66,0xDBEB98AF08AC239E,0x827D04C2CA1B0D87,0xDBB12CEBE4EC4DD2,0x31669C51782A9C22,0x27D592EAC73369EB,0x0544EFD6B6AFEB3C,0x74C9948C648BC666,0x4088A53EC5D9DD77,0x8BA19DB224945885,0xBBF623E050D281BA,0xA5A98BC7E504356D,0x4CB1A8A2917060F9,0x1646E3FE17312877,0x5E48F4C3D318ED6D,0x295A2189CE5236C2,0x5D55A51D17D727DF,0x836F28B32FE5D742,0xD22E93C63EFA15E5,0x0786FDB9DC1F31CB,0x911F293193860772,0x4960C0091C0AD594,0x7F7284E763E5ADEB,0x11175435EFFD99F7,0x7910D8CD6764BF08,0x8C0F1C154447DB0E,0x373960D6A15175B1,0x4F84173941DAA44E,0xAB5EC170AE8F1D11,0x407AF8C559BBDC9B,0x0BF3F36ED7C5E5D5,0x4D31F4CBF236A636,0x38678E06CC6F9809,0x0FB90E5F96E9ABEB,0x3036465BBBB3BF67,0x12FE5466A19E5247,0xFBF1C03BD50E302B,0x5A979EE4C9A0AEBC,0x198E5DFC8051B3F5,0x261651C3D85EF1C6,0x8A16468CBBF1C778,0x4877CA465F49823B,0x3FA2D70AAE63F952,0x7022CBC92DC3996B,0xEA96DF0F55443A24,0x84E6CAC766246A59,0x9DB9048526113CF9,0x1542427EF16921A7,0xDC574DD7E1254DC5,0x0F08EE6ECED8912C,0xED54FBEE9A4308AE,0x24E71EBA400E60FB,0xCFB546387275ABB1,0x0213A0A84972D06C,0x6A1731ABC0093012,0x053930E83019CF0D,0xA1B0FA2F04835D0B,0x99F044BEE5718230,0x9CAA2A43610C58D6,0x7727E5EAA6AB2E8C,0xD612CEA70ACD5D6F,0x13C74A85F9B0E6DA,0x95DD6BB7A9060CCE,0xBD2BFCF618EAC510,0xE6F96B2A662C41B9,0xB8E8B786C9992C8D,0x6EADCEE40FA2B986,0x5A78773E1A8C8D64,0x2688D57ACE3A47AD,0x573256D04C18B0C7,0x365DD2CF8B9CD06D,0x48107C68DED43AC5,0x09709E113BF33FBB,0xE83379BA010D07AC,0xBBF522EB186484D3,0x154BD3430276A07C,0xC669277B4D807E45,0xB964C67DF83306B3,0x219092EC4C355423,0x6C641C8A1CE2E0A4,0x07BECBAB1E63C1F3,0x750F92FC4231A65B,0x080F888C07DFC664,0x6A8F2F4F85D274F4,0x4C74ECBB8747FFC7,0x0D33A2672DA18E92,0xDA47BB2519819D88,0xE02524A8E8FFBBC3,0xF726D6DBA8909121,0xB38CC1489E0E416D,0xDFF118850A9068EA,0x87D2C5A9674604A2,0x559F0B9A01E2EC45,0xF5A88E8D314F76CD,0xB0D3AF61391F3DEB,0x68A886EC6E22ED44,0x48CF2521611C940C,0x13872BB2129F3830,0x577865958EBC16A6,0x345ABBD88713D58E,0x14B2423859CC700C,0x8A817A2B5B4C4518,0xC66180CE8693D40E,0xB49BCDE524BE8C5B,0x11612274CE1997FD,0xD6DDBD8E5FBFBE26,0x5BA0CF65A53A31AF,0xAA68B06540DF0A0D,0x7BAFDE792E6212E3,0xEC9EFFD90B1F0248,0x72240468454B6A19,0x208DF16E9D2FAFD5,0x0519438EB0137849,0x16CF2E1501CAE812,0xB2BA7501A52C5D36,0xA3059EBA05F1FA36,0xABD5802917E5133D,0xDDB6FEF61CBE1E01,0xE6AEA6759E5DB060,0x6ACBB0CC9137B859,0x46FEA4FBCD5E519C,0xFFD85561C84A533A,0xCE9E94D1D4A71A18,0xA474EBF1D635199A,0x6DA35AEBB204754E,0xCF4FEF139F5CD20C,0x6242325939102FD2,0xB835D9F147CC0FC1,0x6524371D86A63FDF,0xFB96881ED31A4612,0xFF9F982B197AF770,0xE07FF625F9FA07D8,0xD66761345F0F8DF9,0xF00DA5C249378E3A,0xFF4AACF26BC6B3D8,0xA4528D95FEA0390D,0x6B41C10BA6377186,0x978AF26C25CC3FDE,0xD15BCEC915D7EA28,0xE64E5DDE6EAAD902,0xE127EE5C6716EC0F,0x902EE8C013DE59D8,0xA5064B237EE7CAD3,0x354D95538146EBEA,0x57831674A3CC39D6,0x4611541BB20F69BF,0xC737054485FA813B,0x6E7A3D80316BCB49,0x358944BAB2B2D7E5,0x1FDBFAC190840089,0x12F4C412DE16D245,0x80A995DEE4B1C962,0x360744C3B377C359,0x96BA5B03BCA0327C,0x2ECFB4AA81C24EFD,0x5EC7132A6B2BEC36,0xF4B40FB350991655,0x6C01FD8A287F21DB,0x8C229A455313450D,0x369DAA31F582F2CA,0x17801DD4F3C984CD,0x5BFCF8078DB90321,0x7B75CFB014CC9DA7,0x19070EBB7327F8D4,0x9196C50F1D985DC2,0x6C9E6F960FACB94C,0xFCF3E40A150DB607,0x7A991DA0CBA8F783,0x1C9B6C43C47AEB04,0x8960319944347FB8,0x43B0CDD2C1F2CAA6,0xB1280065BF99B156,0x623715B7ED01C5C1,0xDED139530D72FADB,0x0FCC212B19B74C99,0x93E0304CD2F15425,0x46C0B442D2A46110,0x099E68CD4B4BCCA9,0x446CA5F9643BA9C6,0x429BE200520469FE,0xC45AEB2BC771B7D6,0x9573BC6752967880,0xE278E9A70D59C976,0x21042410D0661C4A,0xD84176C4604EC842,0xA33C263FC9FCFF0D,0x002A0057557D8E55,0x97278AC9D838062A,0xE038D0E492F1A99C,0xC7F3868FAEEA0229,0xA7462FA60F34ADA4,0x2E4AEFDE3BD24333,0x52B3B26020283CE6,0xB07B559AAB44727C,0xC0BB63272B43B8E0,0x99C160376F238CC7,0xD818699A0A95A3F6,0xE0F510872E57ABE9,0xD14D349890E08AB1,0x1FEC857A093EF643,0x064EFE82DD33BD66,0x7240709DA6F6F7FF,0x3FE621BA80D39392,0x441C1F68424FC6C5,0xB4D09CB812761D70,0x5D1C44E3CAC961E7,0x675F9929A8FA1168,0xC91D2164D8E21E32,0x72B72CF0CB606A96,0xB9C3E8DDA4CEE915,0x4F01FAE47FFC9838,0x9EF537AF29596D56,0x70B886D4EB9120F6,0x7EE11EA57ED8B0C2,0x500BED59ED76BF38,0xD366E568385E55B6,0x89212E0A969875C3,0xDEAD3D3E823226F4,0xC3A239FB1D33A4B0,0x3F4A5041781E803A,0x1384B1C083E7F1DC,0x6FABF0DF325ECF24,0x37B3FDA95BE3B3FC,0xD5F1EAC5BDA98CE0,0x7E896BC8D65DC360,0x9ED672D352DEB6F3,0x41A227C692BDB38D,0xCF57F760D7E8496A,0x32637A622135D3F8,0x6E9B47A29CC1DF3C,0xF0962EADFF970683,0x600D2FA862FB80D2,0x4C6E8D376A7A1DDA,0xD4035F78D3A87D79,0xB678AD1F96DEC86B,0xF0B8D4C648DD319D,0x135D598896B04A4C,0x007CEBA1C0CE0FE3,0x001FC55BCDB8947E,0x72E0B08BECF0803C,0xBEFFFF4585C716AA,0x72BB9FE4FC9FE3D6,0xD21CE4A66AD86609,0x59D38763394BF012,0x1B6A041A509289FD,0x55B24A26D9B78136,0xF3839D18EB621409,0xD4B4BB890FB76E8C,0xE936672B15C827A3,0x074FD7951BDE6253,0x0BEFDD46985356D4,0x90B4E88549B24977,0xB69E2D3BC93FFC60,0xA9DA55FC7D357A31,0x3C9A309F237490D9,0xDB186BB0569B14BC,0xE5F378303F1F842C,0xF546D7AA1FF2E949,0xA7701E28F019FA99,0x108BDC49CE2D277B,0x69873FB4FB63FAC3,0xA0FA2E7BDF3D31D5,0x8467C1D19FE15A19,0x8740B432A391A19E,0x58F2BE9D0BC8EEDD,0x57A0E34474EB4A94,0xC43E9B978D11AEC2,0x4DC1AA0AE82F5FDE,0x440035AE44F7082A,0x61426A80C5C57BA9,0x154DEC064C122E0E,0x37A9801F59124A05,0x8214340DA7B1DA47,0xDD62B4D8FCB2F1EB,0x12E712C6A9EC56A2,0x9C7C98E08ABE3488,0x4DB67B96B8DFAECC,0x846B839E0B49EBFF,0x2EA707D6F47C1AF8,0x55B94BF9D852DE1C,0x2B9F22393976BC46,0xA87D32678A665A0B,0xEB91FB82B0BB73B5,0xAE022C81C8A28D21,0xFD3B563A743FB9F2,0x98120D938B4824C0,0xA7AC0E95A010129D,0x54F2EAD067959E98,0x05E4171D191B7AF5,0x21DE46196C4C5C3E,0x09515A8388D7D659,0xF0534CB586624285,0xB7C1101A4F7F995E,0x72A0C7DBBC81769E,0xC6530488B58F6BFA,0x9A8D47F134EE5E5E,0xD52721A59E729AE9,0x1E3A0627DEC5A2E3,0x14F6D5B643A6F222,0x5E6DBCAC3FB56A0B,0x1ED7A1D2D8B8E410,0xF5CD8F344370022F,0x2BEA5CCEBBA0A546,0x570399A0326D89B6,0x7655AC63EEEE3398,0x0B7B5E75EF6C4658,0x2F09A0D5141AEF95,0x67A5B5CD047A5E25,0xAC8AA25491A277F8,0xFBD7598B601AF319,0xE22C3C5EBEFE3C12,0x9CCB94B04417222B,0x548C0DBA00CA27AD,0x480B7997469F9651,0xF06AA87242A424FF,0x19BD12D92BAF54B6,0xE6A04A21540E9439,0x5870E83187687583,0xE028C2C3F6178C1C,0xFFDA595B07F17E45,0x1A06E2519A8280EA,0xCE145CAB3875EFA2,0x859CF89A95F09360,0x8300098DF0A1C49B,0x6A1C2D942287962D,0x5AEABEA8991E1652,0xAE6E92DFA3D3FE6E,0x875774428B24C97E,0x88442292D947BACD,0xBF229DD806A80881,0xBC528089CC2FF628,0x0D78851103A7D819,0x29B552F5C1342F24,0x7DBF83E4767A7A64,0x3729AB5F35805AFA,0x40EC452F9DD03525,0x16ED978A26EBEA5C,0xBB185CCEBC6607FF,0x6C7C107E96508F4B,0x99A61F0CA69264BA,0xA64EE6B142D10722,0xC609319EEA9B9E0A,0xD32FB590C859611F,0x874802F824DBB17F,0xE4F67F4EE8F181AD,0x199E520000641694,0x03F8B7F77A20BE0F,0xF63D745418AEBCA3,0xE88C6B1D82E9684D,0x8C53705B092D1F7C,0xA13230CFD96E2AFA,0xBD6962C338E24400,0xB84A40CA6378DFC6,0xDE7F871CFBF1797E,0xC979BF36DDCC20C9,0x951F90ED6DF83025,0xC827C9836A67D9C9,0x8F114CA6C73296BF,0xEBC1C62F5DA493D2,0xF9415C0E313CF71D,0xA9E0FE7EF0B97125,0x99E2950CD625E788,0xEE68D814C6524500,0x04C7C42E50745B7E,0x8572556B4EE3EDB1,0xB89F620E37D0DD4B,0xD0BB26E523F2BFFE,0x22ACA11937513274,0xF11659C3FDE9E63C,0xBBC5830ECD15D7FF,0x8F7D1703EF65E283,0xA3349901A6C7F4C2,0x2ECD976E1B92571C,0x4617AF2CE346E46D,0x011890E58781E933,0x5970A36C4D4064F4,0x4DCBFC91AD4E0744,0x6259DFE4306B50EB,0xD3533F4D35C3BF01,0xD1A137C342C1603F,0xCF961A17B4292922,0xEA4C15F789A40756,0xA67F77BD6105A7F7,0x00A30738AA62A039,0x99E6705C44EF9B00,0x5487A90F932F3EC7,0x8DEA15AFEB36B18E,0xFB1123C7145B3008,0xA408AFF1CBADF5AD,0x06FCA5C9DAED5E9E,0xF8A0133A72E49BFB,0x06E684060A1436AA,0x21A32AAD282DE98E,0x01D19AEB5394B3DF,0x09BBB67A1E93E7BB,0x09E38297F37D82F9,0xE26E3EFAD9377083,0x6A18356E6DE3686C,0xE205C775036B044B,0x62A2DA26096788EB,0xCCEDE17921C1D540,0xA604527FF78BDF05,0x37AA8D3D9EB48EBD,0xA8ED4660D328B755,0x296CEDF249535B31,0x46647EE290CD4C63,0x7830122BF26B06CB,0xBAE9DEF73492BCAE,0x1D2ED56AE145C023,0x9CB1488FCF2C6F86,0x965C8BC1B2951276,0xB4B056CDE975F280,0xD4A7A293677A191B,0xC5C09556A91EF842,0x86ACFA60196FB52D,0x0676064C1C1957A0,0x23B373AD83734693,0xA9E087889C17027A,0x084CF3D251E5FEDC,0xDCCC6B3122BDE177,0x65B85702F3165125,0x084D9D76CB83EFC1,0xAB0567AF493CE0A4,0x89EC622B5AEF1684,0x6B7A3CD2446CE229,0x472F943338B33D5B,0x605FF71A9AD6BE4E,0x6E4E1A932EFEBD88,0xC6E0551851FE7FB7,0x1C0661466120749F,0x973CF750EA5494CB,0xF7BE69B632AD5294,0x6B42D359318FCC9A,0x4FBE08BEA57D211F,0x46562FEF5A8CFC3A,0x557595261944BBB4,0xBE0C4E7E4DBBCB6B,0xADC909F475363636,0x16E39BFF89A54D59,0x971B2651C55FE226,0x7969D0AA0E9A4A65,0x588DCCB8214601A1,0x67A94E8F65D7D61D,0x0FF3739E38E97C0C,0xA612568B4F866EC1,0xC87A5B79FB134217,0x7A5547B8630DCEAA,0xFC378B1DFE68165A,0xCA8E9F21AAA443FD,0x5C51E5D12054EAC5,0x928B8D8AE58A5E5B,0xF30CBC06D6D1430C,0x69CCB0A2B58C5823,0x45AF0797DD8AA0D9,0xFFE812B78098AA8E,0x3643404248370E80,0xCC165684BFF6E3C2,0xEC45089743BC7B02,0xEF8293A09732ACC7,0x4D2D0928656A2348,0x518BED567BDB9306,0xB206566D2ECBB854,0xA09AF491A40D57F7,0x18ABA9A530700864,0x45F08BB8F9EF37DC,0x2768467495927BF1,0xC3F54243BBD1F128,0x779332F84CD8E007,0xFD1534E049F2E036,0xCD00B5706710B064,0x8E3426504B3C7049,0x48B53CE152198FDC,0xE6A93D478E487BE0,0x1703DF173D297175,0x83A3A279577F9712,0x1522C0A076CE6239,0x6AC3BCB9D5DE1D01,0x8C796B8FF6336CC9,0xE0D2EEB8BF0491BE,0xC87F9256FE8EC6F2,0x3E0AF56D2781B101,0x75CA4BE447C50BA7,0x393C4D8B020E5D80,0x3A436F69784CF654,0xBA9EA7C98CD34993,0x833AB603EA698267,0xB58F477BE6168445,0xDCDEC9669D42C042,0x5B9D075D46E6476D,0x45E3A24DF7E32DBB,0xF1789E15852753F0,0x3EFE594BA47DFE1D,0x2829C1D4A9A3C14C,0x8C44EB332B10FFE9,0x81D29DB3AE7D06D5,0x3936FBD2222509A3,0x76BE9D4C6F4C1A1C,0x1DC5821DE1BB3803,0x8C0A15748C2805CB,0x45C5733AC117138B,0xE0CCEE8DFEB11E7B,0x1D770D0D1009EB77,0x254306EED580D8C6,0xB95E6CEFCB85B114,0xC4F849BB13119EAC,0x9817FF5DE57F015C,0xB5A4A6665B49E155,0x844C388BECC8B9DA,0xF2772F3D1BE81179,0xEA7718FB3032323C,0x6438499C9A4DBAB7,0xD36DD23B00412ED5,0x339EC85223C49009,0x65835E4ECDEF0FCB,0x29714AE2092B542B,0x46AD5F90E799B2A1,0x18DA09A8CB79087E,0xBF4F3A911073E35F,0x65E8F682C169D581,0x28D4573CE9AE3D52,0x2F0B62F8E8ADD7F1,0x4D111F6F0A2F84F6,0x8E4C1350DE4F75CD,0x109AA4B9247E925D,0xD5EC582A73A24318,0xBB0E33C76D372D14,0x9C76EBFDCD54BE00,0x00FE0E217C0B329F,0xA344BC6F3DCAFE63,0x317A3A3AF8CC8F9C,0x100CE6CB05516890,0x363B4C2E2D70E8C8,0x6AF62E85D9CE3F3D,0xAA6C3B47F586E8D2,0xA1BCE8BA53CA6CA2,0x068BE95CDFABF6CC,0xBA48257A98A6912F,0x9CF65CCBFE63DF33,0xAA4E48D1573BC3BB,0x8778A2951FE56CEE,0xCB3D2B398B7918D9,0xC26F3116AB15FD36,0xA67A5E3B40E341A3,0xC168FFE92E93324D,0x2640DE9EE92A2BBF,0x498B3F441E7CFE39,0x716605BCE48F899B,0xA2D3061A3D12840F,0x6DA0C1EB9B73FFFD,0xEF2B403B84626554,0x5E4619E9996BA8EB,0xD17B7B1F57A27906,0xF2C7781C38118F20,0x981A1FF3A945B0B9,0x1A83B61F658DD2DF,0x38B76B17793744A8,0x87ADCB7D166871BC,0x4C02EE0D1CFD43F0,0x8C0054ED15F1D528,0x0AFCAF363D56E524,0x4289CA6F3602B64C,0xA7302F131E61057F,0xF10F50C2669CEFA8,0x6202DDF535B9DB2C,0xC639B15C3D9F5017,0x169B6F65C375648C,0x94A720299556BCB9,0x0B1FC189CD190C7A,0xF2B82B61862F4636,0xF4256C8B6864062B,0xA837E7C38D86FBCD,0x41227A6448318872,0x329A065DC52D50E7,0x70EAB72E048E2DF6,0x8494E2A483D2A43C,0x9A2E92C6807CAD72,0x56894409732FC211,0xEAD4769A831A4863,0x4DFBF1C1AC10F5A4,0xD7216CC3407E30FB,0x8C88B5B765EEEE62,0x2FDBB7A3614360F3,0x1C6190D1B05F11F8,0xB8661B34109D459C,0x81CA0FCDFA56BB16,0xFAF28996997675FC,0xC6DF343702A22301,0xDA9252E3F1CE9E24,0xDCC46CB25432CE05,0xBB21AB4338ED5BD3,0xCB134C057EF231D3,0x3644C95D84A9A18A,0xBCA2BB106B740E5D,0xFD8D44BD2CEBD7C8,0x71178D70139E232D,0xB66CDA919F93F582,0x4351E7ECCBAEB0A3,0x908870E1494A5D8C,0x364C28AE02B5D91F,0xE48BBA540331BEAF,0x08F229C8A83616CB,0x26BF33B2D34B0561,0x0D93255B6DCCEA3A,0xFD18801268E79533,0x58F684ED18F0EF0A,0xE1AF44BF91DD439E,0x97A50357514A4461,0x4512BE23649FD13F,0xADBFCFA9255D04CC,0x9DDA91D7F6C6F6E8,0x151EFDFC94555793,0x1A036A606A7B9C38,0xF90ED79FA035AC44,0xC1191C4095707874,0xEA8BA097BA707025,0x059C28F4C513DDE4,0xD755FE40A6469060,0x6408AD6CDBD3A850,0x91C432FD3536B463,0xBDFC60109284D816,0x4369851ED5889D79,0xE0296FE9D633E824,0x343DC2E1A921FAC4,0xF43C90A5DEA9A025,0x790B88824876EA3B,0x3667C6B4664C04D2,0x7ECBDBAF7719E0B8,0xEE991AB3CA6F6ABA,0xE91F7933E8017C20,0xEFBE349CCD074999,0xD4351C9E5929F641,0x9B5034AC843D0E45,0xA685F18B17470716,0x894D379D2A7BB0F5,0x56B7C86C0666F137,0x6E3F20CEC73AA1B3,0xF07C9B539DC44F06,0x63A08BAC786307CD,0xF9D1CC8B7B4079FD,0x6D76BD2D3D951B5C,0x8AAC3142C3EE9F7A,0x100C8DCDECDBE3EB,0xC6383F7BD79FB09C,0x70823E8EE6FFBDEF,0xCB75151151BAD340,0x989DD54859EB31A4,0x0EBF320E76265867,0x50BBB2CEF17E39E8,0xB589688CCBD0BDB9,0x4766E479565E80A6,0xF1CE2AFEAAE73B93,0xB321732B7831DBAB,0x06DD933EB06C5C02,0xA9B0CA900C7E5E10,0x81881E787B4B2BF5,0xE64EA553C6FA49DE,0x4CD0D642C2F2122E,0x36A97536B34A60A6,0xDDA6A4BA5579FA7D,0xC394BE7F7365FE22,0xD8EFDD3C0F58ACDB,0x9CF0EE7D2480A382,0xE9891C65A995EEEB,0x1A28E07EAD7A3A29,0x5F21763D9A1A1D03,0x8B539656F0E2BACF,0x98D0FDC51CD7C852,0x080084EDF9BC2EB7,0xD94066C19A04C736,0x1DE60CE8DFA823E3,0xFD91B8744E1E0914,0xF9E03746E340EC13,0x346CB748FAD93148,0x4D481CE009D70323,0xE3D748610ABD6B7A,0x36BCF44F34E3EB3F,0x18143E6A131C2B5E,0x6CBE6B082D2A8581,0x46DCFD2D2D9C57E5,0xB7EA767BFD644488,0x31206D6586B77E4D,0xEEEBB7E1122697CD,0xD887D775319D9BE0,0x823FD31D903BD220,0xE972490EEDCF1731,0x838890D6779D8D2C,0xFCED38505EAD965E,0xD6C062A49BADB53E,0xE9F5F152DE5BE6EA,0xA4628FFF0D318606,0x6D0BF96A48F1A42B,0xB32ACF68137074DC,0xE58E25145CA1224B,0x466C50FFC0D5FC6F,0x484DB0C953F7DAA9,0xD397463FA28F8216,0x474EC85EE985AFA3,0x1AAF545A33044EC4,0x79225B4E6AE084DF,0xF986E2C1B240D5BE,0x83E2C83894D349C9,0x2AE347CF6F37BD80,0x9658E5818249DF35,0xE162E958A45703F4,0x67F9FAA4716C374B,0x32AE4D79EE129938,0x616A3305D9AB848D,0xF4243B5F4A3E8778,0x15E7B658D37B0654,0xAF339654B91CBD30,0xE6B7FAFA7380C240,0x8A6CEC124CBBC7FA,0xC08548D84E81E54E,0x8AA6EBF57182B476,0x76CC158501087F50,0x1E5B8A1A2410D539,0x28B6858D180C4720,0x251FDDFB2EE60897,0xEBB914A9D73BC08D,0x651FE60D5B3A094D,0x8CDC0E3B9DB5E124,0x4915F414F4032B53,0x5E8840E3C319D010,0x333508315100296B,0x5D6CE7C00676C13E,0xDC32C85A952D82C6,0x1915BA58D84E00E6,0x80E69D9AE1B1689D,0x77DB6B4E4D5FD39D,0xCFA372654A93EE6E,0x4FA0E1756FAA4CBB,0x5A6C454D3C320DD1,0x682CE3A2B4D0A58D,0x7CBB361B8AEC3606,0x3371A50BBF252692,0xB4B4C83C4B4EDE59,0xE840C3509E946C56,0x2819B3319093BD3B,0x555145EF5D60D61F,0x289E43DCA9F05ADA,0x109DF28413E959BE,0xEC4EE33B6D466624,0xA4C3B5FA57307059,0x51BAFB20B417A772,0xEC50A944D616E220,0x6B93090E0A5074CE,0x225F9D5F8A77958E,0x593AC13CBECE69AC,0x54ADAD3BF5EA43C9,0xF7AF0D756365CAC9,0x272C158ABFDFE993,0xA3B48507CF536D87,0x14FECE9675C58179,0x9C039AA81B077E66,0x5E5228035835AD68,0x457DCBF2649864AF,0x4D08B5A2538C45EC,0xB25325AF331BC611,0x35028D3544D7F264,0x4E19F0961329B550,0x4B37CF2CE4E4542C,0x28F93EFD926F8CEF,0x966274E01C850AB9,0x7483A0264D3F0CFB,0xBA63EE61FBBD4BED,0x3F86C098D2020192,0xF7753F8240085FD7,0xA7805141A2216417,0x82CEFF8773F3613F,0x53395F92BD938F8F,0x7C4B4EAB9DA78C23,0x25F30EDF135DCC50,0x99BB7C4B6029AAE9,0x4895413E16907848,0x40EBAAF1904E0238,0xD85C6511D5BAADD9,0x48123AE4A43949CA,0xDDB323CAD3328AA0,0x8A5DC491ACE0BFB7,0x9B4991622DEA2C99,0x6BF194EAF10E6E7C,0x077E1A50EC35488B,0x318C4CE8E6DD8059,0xDA55A77F4149CE59,0x4CD224334860DF08,0x7E14F63AE4A35350,0x02CA0BE62976ED8B,0x4F27DD64DDB68E81,0x332A8F1D9601B16D,0xC8B4DA4CF5CA146E,0xA657064CC37E90A1,0xAED48938071AC7B6,0xA85C77603117A944,0x471F4F5DBF78C814,0x55B9DD73F35DB271,0x50C2426780F86516,0x88B61E1F0CE1243D,0x8CBC5CE49C90D1CA,0x1CD3D3E4B0F6E09F,0xD0E2943856C962CC,0x191D4B47831FC000,0x13D7C3A1483912BC,0xADB8607566F14726,0xB19E0B580F70AEC4,0xDA6F41237312B2C1,0x7F2F2F4D5D4E4185,0x66328A65C7EBB4AC,0x65E5B7D0832CAF61,0xEBE9C6781910E238,0x7066F8A27C47C1C8,0xB59F64B1188BCDB0,0xDB91C6D92D25441E,0x89C41D7B588BFD49,0xAC9F7311FAE573B1,0x7BFE1E3722DC8F04,0x79DF82CD98CFD301,0x8C0558BE8B23EE99,0x969BA0368750E032,0x0149B8AD4FC53862,0xF4A3029BF3A0F91F,0x95A9752203B732C1,0x8E90CB9EDC28DB8B,0x08AFE4D952CFECA0,0xC32B76CCDAA2FB4E,0x03FD49744F323296,0x17A3DA50C74043B1,0xE1B29E045A1AA10C,0x63F521EF2562026F,0x7C2527FE8D2BDEB8,0x49F22C110FB9C8D8,0x424C40A49CE4996E,0xB660FFBF928E8922,0x85FF35C879D2F512,0x8D65FE757190DF86,0x55ACB42B21ABF75D,0x41150A8AA5159EB5,0x59CC4873C9A61985,0x71F5A691FBED3FCE,0xC6FFBB3133CEF16B,0xF335AF7120C7894C,0x5DDCE0AB4C21414F,0xD6398B9B81CFD465,0x5AA5BCC43CA1B3E9,0xDED542EFF248383C,0x1087FBA7AF9993DA,0x41E71C2D7A299B62,0x1174A61B4F9F13EB,0xA46063846C3B9C36,0x99159122D3C28A8D,0x54B2F5573F0EFB15,0x380044DD6591F864,0xDF054F19DDA311CF,0xF9F25663EF2A7C5B,0x915CC26BF08FC355,0xCE4B1DDF455337D3,0xFC2A28E6C0537784,0x096DD6095B94DFC2,0x31FA6D7AC9CA2DF7,0x8960FFEFECED3B80,0x62C7A05A794DAEDD,0xED9D2BBD56C8B284,0x18915A804C71A94E,0x516AF026F73BD6DE,0xE98751E0B2DC9020,0x0DA4BDB4635D4457,0xF83FAE6FC3DFE48A,0xC93A259B75EAEB4A,0x306AF779F00497B3,0x5CD8231327CDF77D,0x37251352B2D048A0,0xC1163FDE4886DD7D,0x172FF853BFDE500C,0xB90AC5D1E73C1DC7,0x2D192DF7115DFB0B,0x880A6589C5834CB0,0xD0F3325C70D577B0,0x406CB47CF186CC8C,0x08C75BB72EB69A5E,0xEC3A72BB193C4A81,0x07A0091EB72D7128,0x9092AE65346AB0B6,0x80D4A163C9EDCD9F,0x83BBB5D75AFFDC5F,0x59DB5D3A9A9F0EAD,0x38C661799943699D,0x9C767FDAA3A80CD0,0x113B8F2CA1224CD5,0xD11390FA6E7DD988,0x2C194D486D45660A,0xE207E669EDC05B37,0xEB723C38DA0A8D84,0xDE2EE2642E156557,0xE2D2C5FBD46BAF3E,0x99D3912088695C97,0xA9F8F0B54C60C435,0x1EC2FDB9713D3EAB,0x570926C07E725EFB,0x96C0579A214EF634,0xD6E8A5F22AED104C,0xC58A07351337763E,0x10DB00CC29FCFA20,0xACE2DB37ADC1B25C,0x666C1C844D9569E6,0xE85309B4F25085AC,0x0E22DA85CB94CCAF,0x9233F70F67202142,0x18D848E92E49837F,0x0E635BD402B7E36D,0x3D57CA6928CAC1F7,0x5D174C751D879B1C,0x90644CA5637D46FA,0xEAF4B5274A8C5B02,0xAA47DFD471365510,0x0167072EADA6575E,0x1D1C6671A3375854,0x6A26123D5F8ACE37,0x665C674AF4B1ACE8,0x339E3B2EDE7A45E8,0x58C390229DA10F70,0xEC980BE86BABC0BF,0xD229660B4FD5A633,0x0B5150305B8D3318,0x6CC011AD92BC1027,0x867AB89F7A830CF0,0xFE0A20B88B37DFBC,0x008BBC5F3902B58C,0x8EED57006C57C738,0x41A4EBCA6CC02D1A,0x3A4FEA9EB549E5FC,0xBB32DCE9A88CA475,0x4DC393912C26C7BA,0xFBB022E349E36372,0x167D69346BAB5ABD,0xDCE15244C6169D38,0xEDCD59C93B8DC30A,0xB7A92B7824B73656,0x22BA695E169D6DC8,0xC59485BF18E3944F,0x28756FD94747E94A,0x759CB71A94CC1113,0x64983938085D155F,0x794B9A668C4D9B37,0xABF22C50BE923121,0x6A173C57AA29F7EE,0x2E57FA3B147FE862,0xC3E72FA5C41FA32E,0xF67F8627DB0F58C5,0xC4425F5C771F7D4A,0x5C1F124FF76687D1,0x88FBA1B6B3D88DAA,0x3AFBFC8CB211DAB8,0xEB762B01B640895E,0x23434CC5AC477210,0x0257716B8BD5E525,0xC3F7E1FAD010D485,0xFE79D5BB52AF9CB3,0xAC005A884A4CEE74,0x212E62C19FF3F50B,0xB92DBA698A31E55A,0xDFF3CC7A487724CC,0x9236255BE3BD5597,0x1AEF4ED4269551F0,0x68EBE26D6721A296,0x850E7ABF11AB0E3E,0x6ED7BA135ACA837C,0x8B4A9FEA3CA31839,0x04616F621E01DC7F,0x9BF354D3D617B50A,0x4D0823B92584EEF7,0x9EC08B4E280A709F,0xECF3D4B68A6216B2,0xA78EE40947EE41F9,0x842F0526E62C315C,0x6800E545C33C314D,0x155D6C9A5DAE7FEA,0x8EA551EB9E06A659,0x84963C75109FEA1B,0xE2D50AA666CEF90B,0x0CB9A62B89C9CA54,0x0246F8592844D26C,0x870FB654A48B3E3C,0x8580DB6B7A8D9D85,0xB12EF9BD605EED21,0xBD5CA2908F6C6EE5,0x28BDF7D9037C5287,0xAA51F9FE9EBD53BF,0x1654EB3A0764AB98,0x6605FAE4E473252C,0x732512A70024E2EB,0x25D1B34C7B42D78E,0x52577A0C66308D39,0x048D19AC125715AC,0x37A418A8BEC790A5,0xE58DD34522206DCF,0xC3917CCC6C573A0D,0x06F2B8FC84207D25,0xB71C541255A96730,0xA56BB3A38DF9B902,0x893DE5481FCFCFBE,0x481E549F4A48B5DF,0xFB99115B5701D496,0x914DA35D98B963FE,0xB9E0A36E3D03BF74,0x03E0BCDA47EFAFD7,0xD1494728F345C43F,0x4A9CFB9330E651B5,0x14F2F45B339243C4,0x56C1AABDF37594B6,0xA54CED62F6F354C9,0x6A7AD505C4AC6186,0x0633E06CF11B29BD,0x93CF91343E211427,0xF83855089F7E5BC8,0xF910671695A498FF,0xD9C0DC366A1FC19E,0x137CC6B5823610A0,0xFFE58D4F7D8162F5,0x61B9222DFC2C3920,0x70783DEB4411CA1B,0x2276BAD77A17CA15,0x45192EAEC051B966,0x3C0371BD6AD0E816,0x647283A937EF75A2,0x7DDA975A72C55C73,0x151EF6564612ED9C,0x3150EB4B44CA2671,0x0598F541ED98DE0A,0x8A6303D58552D7BB,0x629AD328E7AFB44B,0x0D0778C9781B2A3A,0x9BCDDD8CBFBD8956,0x323B28DB4CCE389E,0x6AE909E13CC59820,0x41561CDE519108F4,0xF71A97E5E5AB70F7,0x25A64E301988F5F3,0x36A875F70FD83248,0xD19F25B394EE86AE,0x77C25E5A77A2C151,0x37CDB590C39C0911,0x8179F93551D6D459,0xEF4C23C72F927EDA,0x3A56792FE48F35FC,0xB262B522C04F5FB3,0x0F1636E3AF464CA4,0x48222D4CE846796A,0xD6591A5D36364737,0xB5660B6B463EE076,0x3EDFD5D3FFD76A44,0x0075E57E5EFF1B50,0x90DFA3C02A38B3E8,0x56333993A0B7DB06,0x84BFDF28A371EDA8,0xD1A84922839EE50C,0xC0BD47907CDFC78F,0x3881E803D3B1B8F9,0x3B2B8DA20C9E5E41,0xCB7FC88604681C04,0xD86121E565FE6C2A,0xFF586C25BB2C1854,0xF42A3492F423DC8F,0x0748FBAD0427954A,0x42EB42254E28A3DD,0xEB6C348DB3762206,0x4EB6752D24C3E2B4,0x39D08BDE7EA41F04,0xBB058BE2960ACE50,0x09E91316B29C8F1C,0x21678510F48349DD,0xBFD5896878375B4F,0x80DA382C80DE108C,0x111E5E966F97BB2F,0x4CEFE24750A2D0F6,0xA52AFEAFE9382689,0x6F3F56A54A15A4A1,0x43AD7B830E2198D2,0x704AE46FCD50FD5E,0xDCFA0B15EE38B1B5,0x29015B93C13B802A,0xF788BD146F594C34,0x0B5256F6C97C75AC,0x7AAE0AA61464C55B,0x7129A3925C0A6831,0x0C9C0275ECB0115E,0xE8B95715D022BE33,0xC9A927F50760AA2E,0x2078C5A02A1D6898,0xF01827397E8A9224,0xBD4CA8292AFDFB5E,0xD2C63B4C0A42079A,0x99C84428B6DCDE87,0x967011DDBEA88B9F,0xD6732A1776DEEE25,0x40C849837228D837,0xB7C38EE089110DEB,0x601FF0F8CEDCE2A0,0xDEE281358FAEDBD2,0xC3A24048C378A9CD,0x4980EA611DC5D405,0x17F879DAC587AD49,0x25DB4151DCAB508A,0xB5B09D7527B664D3,0x037A22B0D8725631,0x8B64528510FBABB6,0xBD722D8B1778B580,0x3290799718F7DD35,0x0F85F3009ED8D5AF,0x99F9F6EF6B2F0014,0x32BAAA19F88376AD,0x8D48C76CEBB0C4B5,0x1ABDCB72778B7C2B,0x7D14C1973BFF5DE3,0xC8C702EEF47B0A48,0x5F3DF81C43A8258E,0x128742D651A0963F,0x3D848C3440BC7916,0xD49BFEEB2FE64F65,0x2BA1685CD8F75946,0xD917AA65B0D037B2,0x6B50983DA9408347,0xAB52CF3F6AFDADB3,0x8E4BCF496956BAE1,0xF3006E5B395988D3,0xF8E671D89982BCE5,0xDB0080064246CDBE,0x5E23E7846C2481DF,0x7D661638A0D6A40E,0x38E8DB2F4C2EEC63,0xFB87BD7B8E3E274A,0xB43EA431CC6F09A7,0x92702B8AB408BFCC,0xA6004C54B506A76E,0x0271786216385557,0xB4E984D1AE4A5D4F,0xB32BE633732C5CFC,0x70DB5FF6FAD0B9E9,0x9AF35111FFA2D00B,0x03C32434368FB732,0x7B00049C891765DF,0xFCBDF69C7F029CBC,0x6C2AFD813072CF29,0xFEECD19615BB0A19,0xF32FC14061951234,0xBB6476FE124C3E80,0xDA84B8DDDE2643A1,0xB8F43DC05ADEFD4B,0x2958000FC4FE66FC,0x46CB5FB6C2853A57,0xA38CE61F706B5A51,0x760DFC5C0091BFA2,0x07217757BB24FD9B,0x34B13C919BE1A651,0x91B724A37DE5C5FE,0x60AF9F846E18A934,0xEBCA4387917CC427,0xF8E0FCD8327FEAD8,0xFF06273B8627852B,0x9E1CF3F46D5A9114,0xD78CE57A5D8E23BD,0x121C440CB8597C7F,0xDDCF58D6EE6DFB01,0x372B42A0AE38D464,0xDF588E66135C7583,0xF1A8911B75AD0FDB,0xCC308F22A5E53632,0x50522A9FC20FE351,0xA0CC76788A9316B4,0x275E7F6F255102B7,0xA6E8322B2F65EBD1,0x28F10C28BC9DEDD4,0x5C070056972C90FF,0xC2590E6B1583F0D7,0xE7ABA28F2112F72E,0x924052EDA6DCFB64,0xFE89C5995FAA5D5D,0xD4EA50396FC07229,0x5A83FD40B8BA7898,0xBAFF05AB3B0D2E8A,0xDDADC92F42ACFB49,0x1A90D2AD5046067E,0xD6402866C6D5BE42,0x036EFB25EA83B2F5,0xF2E90A6AA83ABE0D,0x0837D26EF403D1A4,0x09E20604B2A92E31,0x3F28EBA85E657FDD,0xEB03D122AE76ACFB,0x1723D3ACD8784D20,0x76D53CA646391CA2,0x5D8974996D096522,0x0F71D32BDCBEF671,0xA30CA06E601E1D3D,0x1C724F77D62092E2,0x218BE2C164235BEE,0x262A2E1FE963323D,0x976FB5B925A2FCA9,0xB21010FD39533146,0x593429FF8C87E883,0x51FC020A7C167919,0xFE909E3FC72426A9,0x6F80D1789A9F2387,0xDB5BFFD27E691865,0xBBA21075EE994A52,0x52681723517AF8A3,0x570E3A3738CF64B3,0x97595BD0E4F2D287,0xCCB588AD406D966A,0x79C9A0861506EC5A,0xBABC993E7B81B8D0,0x80A0018392879588,0x49B38D7D67EE7035,0xA9A7EA942B9F8792,0xF768ABE675E59EF5,0xC438E6551B19345E,0xD3A9C0D971ECA6C5,0x1FF4EDC008894B26,0xABF63BB26B4E9902,0xB2B869CFC3EDDB3B,0xEB21A92F89EDEAA6,0x308DAB97642B045A,0x9E97C604DE26F8FB,0x560429BB9E934BEB,0xB23138322A3311A2,0x5E4AF5BBFDA474B3,0x94385220BA7C5720,0x1533D8B229D27C15,0x97CB94D8B436FE6D,0x9ACDF16623A8095A,0x096A7BBB6FDAA174,0x54EDD4703A6C539C,0xD2EEE750BD27088E,0x958EE035D6EDD992,0x2B19C3B08517B964,0x2B38AA6EBF91648B,0x521793AE5C4BE4B1,0xF851F3989B4FD0FA,0x3F575F130BA2AE50,0x5599D01842BACEE4,0x3A1E5820C9040C7B,0x050C54E92F34A2EA,0x328FCF851911638C,0x3F1A8663E228FA02,0x1505CE8CC38806A8,0xF9B27639609225B0,0x77A8585D9DEE21DB,0x2537E979321C153B,0x48613B066F7563AA,0x331A6D0EA345732B,0xDB946FC261DEC80E,0xC563DF374A6B46ED,0x679A47B474F4DABA,0x5D6F22DADDA92560,0xD6A0980F7DD8BF2E,0x79A55F2D63D45D7B,0x31F711219DB3A602,0x90AC7B299A277842,0x67AC1CBD04111DD6,0xB97DDF2EF3E7306E,0x48D098296B742B84,0x1F0503054095C6A1,0x29C18B027F20AC73,0xA17E2AAE59817770,0x63787A6DDB45C2F9,0xA7D1A3F782B863C0,0x3E68B084356EE4F7,0xF11C1CEA3B07593D,0x42AF839450ECE0FE,0xF9866EED48238315,0x2146F9148493D7CA,0xB26520383C9F3BD8,0xEEF8034DCDF5847E,0x56AB9BBDCC4F5A06,0x03BDC92B992EC716,0xC01DFCE5E2BD9438,0xD157E0D0B5B7DA21,0x2F4CD40894678684,0x4693A738559FD27C,0xF32878496D82F627,0x9B580EA8EFD7E127,0xF96450E14ED3CA82,0x9234F317EDB0C29A,0xC860616CDFC7B207,0x8129FB815CFBF370,0xE106BF330AD7C0F6,0x9FBCB07F487DCEFB,0xD861D22A6750DF96,0x6828339ECC6616A7,0xD06967CFE804DFA6,0x82CA6A5D604F40CB,0x8849C8CD7C8763BB,0xF2E04AD08FC80FB6,0x6AA60EDDBEA53FDD,0x86896C2331700984,0x9012A2830A8E387B,0x7786856B53A098BE,0x9FE1DFE693602486,0x24C7B36ADF292999,0x6C941A72F4A406E6,0x84DF25A641C4846C,0x956C95780D9FB8DD,0xE1BF8AB6E7D321B2,0xFB82F528F8686300,0x59F099BAB64CC9A3,0x906755B8F095B212,0x688A8A52BDF5A256,0x5424F80638DC0729,0x3D10C78FDB7BFFD4,0x3CABC13A21386AF6,0x2866FDE2EB5E9F3D,0xE14E99CCC90E0F31,0xF519BDDCCE8C817F,0x0254CDF844011E89,0x80464AA657E6E85B,0xABF8936860BDBD14,0xBB72BC81E66D2813,0xA571F6F76ED6B846,0x6B54AEBD4211963E,0x7233C876D1246F53,0x137FFA318E9034AB,0x9425545DE98525DE,0x85752F571FDCE7D7,0x48ABABFBF9530342,0xBD4A0DCD800C3062,0xEA40E61922FD9E59,0xCD7745740B191564,0xB7686B29874F8DD6,0xEA1D5EE068580BA2,0x21F2B1B85F83AFD7,0xB4BD401A4D89CBEB,0xE0FDD5E94833EB55,0xB000EA773367FE19,0xF7FF0094A50BCC96,0xA6E3C7B361DF1545,0x4327596776928C93,0x7FF8FDAF18C4AAD4,0x4CD015DD9A5CE635,0x04F9FDB992CA4D17,0x072B8BDC506974A5,0xBE619F6700D04D91,0x1590B25E797DD6C7,0x9D013405967E9F7D,0xFC6BF31B6E9C5DFF,0x41024106FF385614,0x9C47CDC772ECC803,0x93E3F13ADE47F5DA,0x0F91BC6D18796D8F,0x38DB96D837EAA54D,0xC6E1316E244B1AE9,0xBD705449C1EBA288,0xDC14A9090344D110,0xE9C06BD70BC64272,0x80C6C928B21A25E5,0x6662401EBD5D4468,0x88D9BE3217B9A5B8,0x4D0155C607389F4B,0xC4BF2005992C2793,0x3C95693E67B19B92,0x03C9E08AC3FD2C2B,0xFFFB35C57586AB82,0x911A43FE52ED2BCF,0xDE5208A3C9DCFD0A,0x08CF93BD800B0930,0x71F18C384EB681A3,0x7DEDE77B3C5186F0,0x0703CEF1F32BC6D0,0xC761F5F87DAA68A0,0x9E866665DC352463,0x74A9C60788328DC1,0x2832A3350C7C9928,0xF776B882F1FDC1CD,0xCD735D9F3AF281E9,0x60A3CDEE2C89C6AF,0xD2DC0499CBF636AB,0xFE590D77AF04C8E5,0x0C653EB703054646,0x387D695EEAFED03E,0x440B5ADB3C796897,0xE4BFABA2470FDC9E,0xC9EE4DFED8A7200D,0x1F9D0ABACCFA8CF3,0x3FCC4153DF5DA0A0,0xAADE5B9763DABDCE,0x46316AA39DD39CFD,0x4E597C1F2F27168C,0xC54F15509A8FB0C0,0x63BE16B78CFE584E,0x35E75AA4906B26B4,0x9FCAF8F7E99EFAC1,0xEDB4703CEF00A9A7,0x55DE9BA7AA400F5E,0x4C761D9BDE0D5564,0x3DD9D625BB3CCD68,0x84C3DED2C9119234,0x6192397CB9A7CC8F,0xCD0DC24C1D42BB42,0xD43A287EFA1EA3F9,0x8E5A7834C29B82CE,0x1566BCBD4FB0B49E,0xC677C4B2610D930F,0x6ABBE4C51CCE2511,0x93E628D4D3CFDE4F,0xD3AC785EDC09B4E0,0xEE26EA64EC769B7A,0x52372B065A7E6981,0xEE90A546390D87CD,0x7EBD556D98D61622,0x88212646DC1874B4,0x62B76EA14F3FB6E4,0xFC832B2272458741,0xA587460D16F530D2,0xC12F62F365D8CD24,0x0826FBE0BC0EED10,0x80913204C748940F,0x8569FD2E2907C6F9,0xB270D53FEFBB4459,0x3672337F8EAB1385,0xEDF3D850E21684E0,0xC2EF37496B927650,0xCAC2860F2780ACC3,0x67CA7019ECBA9317,0x072202732A33C915,0x9D1233ECF8141703,0xCDC5EEA149642A2D,0x4AA893EA68CD140C,0x27226FEDC16C9F1A,0x290DF162AE6C95DB,0x9F76764E5C3BE5AC,0xDBA2B351A1BD0631,0xDDEC0D6098BB918A,0x82104E1C927FAC74,0x85D4CC2780EC4BCA,0x838BB56951E228DF,0x67173805F782F217,0x74A2CC5DF977C412,0x3154CD382B789782,0x3AD0937E677D5B28,0x8D3D715D03C89C79,0x5802F2EC4346EE9C,0x7338E61A469A71ED,0x0138ED82541B82B3,0x19C0212696773695,0xBB57AA448336F461,0xACE68A810D916B22,0xDE823F0C3CD56CF4,0xFA510ED6038F0447,0x00D62B47A90BF6C3,0xCE98471C08AA1462,0x074B8102EA67B8CF,0x3A00B2B96105541E,0x8DC5721E71E6F12D,0x5A06D078363DB66C,0xAFD3B033CD8CF6A9,0x174C1BA74815DD33,0xA2C8227578FD1C65,0x47420956690223D9,0xA6FAF70334860041,0xF99DBE71CBB245ED,0x3B3B293FFA16750E,0xAD319D6E81324C2A,0xB574B3265E65926F,0xE588E83F046A24A4,0x64DD40CB83CA5140,0x678FE3A51554B0F2,0xF84569D3AF8FFB64,0xB09BE92BC1F1D84C,0xC3724A0BAA3C4C1C,0xE2AC234CFC00B967,0x010BADC114073326,0x5F13DD015A348820,0xF4C80BBCEF664A64,0x6A549C7941A304D9,0xABD451274687CBC9,0xE48769948483C39B,0x4E18C501718163A7,0x67D2D67966A1F994,0xF3E4E3F08093E2FF,0xE9E9171FFE3B6ED8,0x09FA4E1BF17689BA,0xC48B11BEB01B9FC4,0x5D4EC59559E5CFF8,0x93CAB1282C136975,0x3420E23851DD57C8,0xAFA40A2073751B0B,0xB74F0FB82F071E00,0x88A048CC93BCFADA,0x780D5DB4E9B387F0,0x1C70C78BABB6874D,0xDF83E91FC4B096F8,0x9D2DE363E30A80CC,0x0310044943451F21,0x05A9B688A3F2BE55,0x15B9445592A5D45A,0xEE116D1549FBB573,0xBCB46E4EBDBB0563,0xE21C07593AA7A21C,0x168F40D9010F7B9B,0x27830BD8B58C4D5F,0xEF9A66A9267D91BF,0x5B47452F9CD66FFE,0x40FACEB75C01DA61,0x726A73F7F829886F,0xB07AE0E015CD6FB2,0xE329715AA8D6A899,0x9D0928C5D02EC340,0x8A2AB20DDD649265,0x9DE6DCE99CB8F731,0x70B77064C1E5F197,0x8BB8F0BB6CAC3647,0xD8623E15E5B5BA85,0x9EEA6E6466E47FB4,0xFD38E2AFBEA09C9B,0x04AFFCAE8505FA52,0x2B0EA5AA5DAD4355,0xFC3F203823AA4AE1,0x3C05C9998456EDE8,0xEAAA8D59763D66C4,0xB6898D7176221798,0x1D87C2BE759D45A6,0x7510F0D3706CA2AD,0x6DC9234EBC8F319B,0xFF167993E114A4F3,0x51A940B53204F598,0xE847D96DB66C7CCB,0x1BF0E2C7BC41A606,0x344A8E61B91587FF,0xDE0F4AE3F84B9F7C,0x8260EA1E28AD93F3,0x4F32AACC2B0695DF,0x355D60ABA7EA8EB8,0xB072D42F2A9F47CA,0xAC0D771621506320,0x15C42344B8C24D5F,0x1872F44B03F5B31D,0x751C8382F6BF8C9A,0x75C048D6325697D0,0x8E631783E6C7D586,0x720F02B590091193,0x1E7C79BF70DA2F8C,0x81C35F917A6D648B,0x79053B485109396A,0xEAB5A4DF722FBFA1,0x00FE007298EF39D5,0x29A3D2F8C6D6B0A7,0x84B0E8528F9D9F73,0x0346C34B65BEE0E0,0x87F9B9B3DE7FF0AB,0x8E51BA210999D159,0xDA007353D19DC3A8,0xD0EC3D9A9678B701,0x1964A47F0D1D99D3,0x479757A98199FD21,0x987DFCB1529F7A34,0xAEA54C0477700A0F,0xA80044D9D121FA0D,0xB01605050403191E,0x5FE5FA8A74DB7850,0xDD17691410D0F597,0x4A0D14060C01EA6C,0x4C77CE2C0053DB99,0x06F794CA7B2D2793,0xFEF6B9E3B4183134,0x2B4A58A7A72A8FA3,0x1BB9B90B1F19839A,0xB0779E45AF23BB1B,0x2A6539DCBE610404,0xFFAC7778CDD99B31,0x55B943178320D224,0x172292CD41FFBF88,0xC241B01A15E4D8D7,0xE293D8A4DC99E565,0x899A73A0B8AD8D0B,0xED09B49FB950C95B,0x6B3AB3902F4C755A,0x096EA06BB8ECB4DE,0x13E8D7D1A036BD06,0x22419C237F1EB797,0xBE27B570BE239038,0x90F2F19905E4459F,0x038221008C799F30,0x0809B0188D67AFAE,0x0B086F4EA700FA97,0x153A05646E493106,0x2D609408C8A2F064,0xA601B78BF35A2226,0xDEC18E8C096160A6,0x1669FBEF27D5F995,0x34EE3D28FF4F3CB0,0xD40457FAA2A5A78A,0x2F4A502C5741B4D2,0x21F4187091F3EFB2,0x575BA43375680CE1,0x82F7FFB1535F63B0,0xEE50A253E6C339ED,0xACD15BD0553F85DF,0x22FA2132EDFFEFF0,0xE452CB2BF3EB66BE,0xDAE7E4B83A14212D,0xA912CD38C5B0CD86,0x56A082262ED9EFF0,0x4015EB2F261E6F80,0x363E97B9BF95B366,0x85F5F1C7003B452F,0x796485CD02CCD790,0xF8490A80A8B0A957,0x68EA69E94420555C,0xFB337D5570686036,0xE9C017417E72CA26,0x3982B2875D5851ED}; +__attribute__((section(".data"))) sh_uint64 test_values[10000]={0x0C1A206B9E7A2315,0x834A062D5EC5DED3,0x4C267494A20356F0,0xD808150748702064,0x4C045919CA68DE43,0x61EEBF67B7782F44,0x9EAB5F0A80088E32,0xA5B1ECEE8F7EF30B,0xF6D0D72B78441209,0xAFCC2039D1FCDD6F,0xB13BA585D7B17301,0xB117D4172727B9D5,0xFA6D1C3B5A9AC93A,0x06BA56B2A654FA48,0x3D7B266A57A171FA,0x1EBD708052EA4D0E,0x786BE1585443E4BB,0x11977650D6E9613C,0x59D09D70907E66A3,0xABA42B4259136064,0x9B23A6496D55E665,0x81828E47A5F88988,0x564511DDDACA67EC,0x450BD22C25018122,0x2F0920279721B8B4,0x30148171EFDE7BBC,0x727F24A940A9840E,0x785AA211C52BB236,0xA4C033A1F10A2D3B,0xA657428C044ABED4,0x7A808C446E2121C2,0x3C821E1B973086D0,0xE2B0B332F459801C,0xEC52D532C3F864EE,0x10BB67F2B8D5CF06,0xF0C1DBC80E7206DA,0x5EE0A983A896A232,0x3AB25E7887BEAE1E,0x802C7F2175520EEE,0x8370A44EEE7C014F,0xAA3CE507D8C6CB87,0xB908F852E4426F31,0xF6B98607C95250AF,0x2195AF270EEA3A25,0xF0D9430D1538D9CC,0x1D458F2CF1A5C02E,0x53537DF2C27D301D,0x247004F5AE730830,0x30B77A966800570C,0x3137D326A862ACD4,0x2C4764A1E4392292,0xC76188CE002EDD40,0x611998680262D16A,0x4CB0CD572B5C0318,0xF79DB33ABACED080,0xA310092ACF669FD6,0xF541C3111C2F4448,0xBB728AA5519D6180,0x8CA529F9E6018177,0xC5BBD96A87311A2B,0xB42923781714BA1F,0x13A4BFB1CF7670BC,0xB7EE50E2C12522B2,0x807919B42B7346CF,0x0C69397D35FEC83B,0x22FF9F6BB2C01376,0x6E45624A9610630C,0xC984E06633823596,0x72ED391D3311362B,0x106E6E3F2163F879,0xEDA0E571A50364FF,0x34C9E0EC29A69B2B,0xBC879E6106F93FAC,0xE27F1605957F4404,0x8C0D00F3A5A8E18C,0x633D7DA1C2A54FDC,0xD43B27337C8A3DE7,0x83825675662B0703,0xCD0C9B27A4277651,0x7A4702370178FBB7,0x25D0A89C5B6B51C8,0x22FB7868A0C56F10,0xB4765ACDDAA9BC02,0x23FCED569AA6C8EC,0x800A22FD0E365B77,0x0FE3CA07E5DBCCDE,0xB2922E1F588E6433,0x2D0AD18BFF79BFA1,0x2646B9708079D89B,0xFFA82A7A59C8257A,0x61F0C02FC45C2108,0xC62002E839955475,0x8B0113717A854CDC,0xD8794566DDA86BFF,0x4B44A926408C533E,0xFCBD9E0E65F813C9,0x8577FFB3E5AB4896,0xC87C3E0227809029,0x2329CD6C01474B3E,0xA7FEDD05F709970B,0x3FD7FB7599AB7924,0x3CDEA97CA15A85CA,0x0682965F8086D250,0x2288FD8DE4A97C24,0x033ADFE6EC4D142D,0x570443B5F9B16586,0xEBA0904F52792772,0x27C6E7201F9EC19F,0xF0DBFA0851432F4A,0xD986564E94DEA354,0xBE330AE0E7A4A3C0,0x65725DBB271747E7,0x47C5F239F756D63C,0x184BF3D243942FF0,0x33DBB1E51480FEEB,0x16B9A963C35D40EC,0x3348998863071FB6,0xAC191C8D2774093C,0x17168D0DB086A87D,0xC6C5752945558840,0x14CC399AC141F48E,0xBE43E053572BBDA2,0x9180ABD088F862A8,0xC96BCEB35A9AACEF,0x769AC1A1FA66BB9D,0x5CD13768D5EFBF33,0x8C9F69088AF80E24,0x2944045809EA4719,0xBC8FE972DD71045A,0x1D8503C4ABE4D09A,0xDD2C0DE33CCFBFBC,0xC88436B7B2F449B0,0xA701F56C1FB85B03,0x12E0F9CCC1FAB965,0x91A2DA7D75F02A38,0x9AB4434FD08B283A,0x958D91ED70C1A66C,0x81505F0DB317C7B1,0x76B8E26C60B05650,0x12874CB1E65859B5,0x0F41D5CAB091CF1B,0xE3A05D69BBAA6DEE,0xD99EE2F29EA48FFF,0x8854BE08E9499EE5,0x0F2E9CE719322811,0xF41F4B45EE093BD9,0xC3B7E0682202FC1E,0xE25414CFB0C78699,0x343ACCCCDBF3B780,0x870DDB1D135DA06F,0xC3B9D504AF77C4F1,0x4E70E45C02A4CD5E,0xCACEBB6F3D34E98A,0x5BA30A1058E46B4B,0x1A368AB9AC6D6842,0x5A98C6475F7679A6,0x1C52398AC94A8BA0,0x3D81BAD686679E6D,0x13F5CFE867064E06,0x1629D6A2D5DFAB98,0xEAA3419D3644E91C,0xD5ECE468C7748442,0x2314E49A516B7B8F,0xF8166FA71CFF9C5E,0x3BAFD4A846974530,0xCBD5201723D32897,0xCF8ADB6E8474CE52,0x0A348ED89308184B,0x37E5915934B2184D,0xB6A5BB2A36128ABF,0x7B0567A735FB7723,0xD4081A50A7783CFF,0x6F99F3B36BD9BAA3,0x21C339FEEB193BB8,0xAE8282CA0DFB3279,0x602459BDE52B0B55,0xD8EF6D9130815471,0xACD1F615A74CF38C,0x386D7D2BEE5934D3,0x89373A1151C4C45B,0x4FEC87F2FA13B29F,0x33B543B02E4550A0,0x9A73F927408E2A60,0xB7E9B50F555210CB,0xB422D463F128C2D5,0x9F2890F9D23174BD,0x9EE11F7ABC6F3B57,0x97471565C0576A17,0xD07D6F29D82CDC50,0x51B136D349BE8F6B,0xB4E6977F38B4A753,0xEFD61A1901B8E83D,0x597F81CC6E0C51A9,0x4F3688966AC0B512,0xC4A47901F6940CA0,0x1D650E0A3E739914,0x02E507F8EC4D9431,0xFED25F28B9A74BB4,0xC4DAE6BBC4511778,0xF384F234707F88E9,0x03CCAD234C9BCE1A,0x06954101462C8B43,0xE3C67D9261AC6A6B,0x2AC6BD7B54F5973B,0x756B8386A51EAE0E,0x9C9A2B944A9B0DFA,0x22F34E0D195ECDFC,0x28CBB08B4FB199E4,0x7F5292785D967F34,0xF6DAE3EC6F24A563,0xFDBF4EEAD377E642,0x10E0494A0E18BB42,0x4D4AEFA174D1B18E,0x99B20355BFA54C7F,0x76A4B7529CBC0D1D,0xF380F1B30DC0253F,0xA2F557EF60201718,0x9CA8A885D5C590C9,0x974244284E75E13D,0x4BCF38EEAE467813,0xC343DC99FDD8896A,0x411AE5CCFA7EE123,0x22060CC28F365FC3,0x575A1598D7C7E1AE,0xB9C57F721F0F4D45,0xA9E184379D5AED6D,0x584ED86A3392D56F,0x50987F78AF769AE6,0xAAB5EE896B543D8C,0x418B559A337285BE,0xD64D1ECD968E5D13,0xB88413F7EFF3147E,0x8CBE11776BA7E7F1,0x9B056B723F019D97,0x1E9BF8F279131075,0x6D16235678109F53,0x7178488CA16DEE12,0x98A0BA2E02B16ABD,0xE8A695743E779BB9,0x10375EFC7183494E,0x3ACFCFF3A6417AE4,0xC10FA3CF5F0C7AA9,0xA4B8C12752213739,0x6F0ADD829C72C9F9,0xC2F0FBCAA84F9BAA,0xE6430803F2EB4A58,0xCA92927E0848DE83,0x08C661F9D60F7898,0xB481FB9D115031E7,0x9865ED3D980BEE8D,0x393262C10BE1A1A3,0xAB91DF6CD486CA4F,0xE94637A43812F66C,0xA6EDC0454AD76A72,0xE7911F843AC522D2,0xD4EB9C5C4745461C,0x7C64F6FC64F23DDB,0xC66AA1DC1EE1E2E8,0xE2F776CE3C6386AA,0x693198B0227E30BC,0x5ADA9FEC8A5DE8A5,0x035368435C759875,0x42C31FF082E10668,0xF7BABA032F10E1C2,0xDDA2E8CF8DA0157C,0xF92CB8B58F059413,0x5005439508AA23A5,0xB8ED6CD87FD7A44C,0x3E9D98FCCFCE2B82,0xD369709A431EEA3E,0x78F17CE838E7A6DF,0x54A21B909BA0A99F,0xA78325F3A5F3A110,0x068A0A557F9EF678,0x35CCCC8ACD4C0525,0x05524A51CB55CB9D,0x80A2D0C9BF3ACCE6,0xE1D88B00A57B8089,0xA5F71A519F5429E9,0xEE9913322F18BA83,0x4194572A56D5EA6D,0x8492453BDD9C37B8,0x757E3DBAE3B62855,0x7064C28C5A0FA9F6,0x1EEB868988D7638C,0x007651D7E25450D9,0xF15BA021C67B55A4,0x8CECD40B59792DCC,0xAA2072866CBBA4E0,0x36B88DDD513A5B77,0x88FF12E6C8A578A7,0x48986A3EB06D5D24,0x723F9CE429A3BA4E,0x3FDDE388B8EFCC59,0xAF275CEAF5D4FAA1,0x343DB14784A51283,0xEB94B6DFCBB01FDC,0x64120276AAEC5F8E,0x9380F024D2BD45CB,0xD832A25ED75719E4,0xD6DCA25FAB8E6419,0x4E2A06EC4F735413,0xFBD8B54C339E9CB1,0x900F72AD05CC8A97,0x6BD22E31D54B7CC7,0xCD0B60727A350B08,0xD1539B67DE28C8CA,0xAF3323FE26697A5D,0x71F07A27FDB20F5E,0xE5D630414974091D,0x326F482627ABAE2E,0xC22B894128678495,0xFBAFEB9E91892A77,0x211AD31547E01987,0x9153934125B1BFFB,0x84C68F1F40CB9E76,0x926AE49FAA599844,0x895637217C37E0CB,0xBEED0C267FB5DA16,0x01562A9BB5D58330,0x06B4E061F68785D5,0x339F6EAA272D47C0,0x94DE98585143136D,0xC843DCA5C152193C,0xEAD880BA9F339035,0xB46D6F8F0046164F,0x0C89F87FADEF6A28,0xD15B0C8D72943EAA,0xC26362CE877980A4,0xD5839F3AA31866EB,0x8E3CA88D87545BCA,0xD8080D1047592A82,0xA15DE8F1E3BEC252,0xFF716879BF8F74DB,0x96C1AB8DBD1C5788,0xB9A6D1E142EB4218,0xCF8E83A8EB71D51C,0xB160D65F2A06D186,0xF2AA4ED6F77D568C,0x16913F6DB6584ABB,0xD407C96FBD04D63B,0xD71E9376C2355074,0x935F196AD41C4F3D,0x87B16B2D346075A7,0x11C3150A239ADA79,0xAF75703CEBCEDE3D,0xC551BB52F98AFEF0,0x8D3B933590C2210D,0xB74AE6053B662D10,0xB795D9FBA7BA9D85,0x226F6201728E5C0D,0xEF5FEB7A06BFA41A,0xCB67849C2EA99ACD,0x4844A2F45EADBEEC,0x88F3626DAD05DC04,0x522828BA18D16B70,0x90CF4C60E3D732A9,0x8CF8DB36AA28C6C5,0xD7442B6329FC4A17,0x39BB03C101C23A32,0xFC25AB1FC754500C,0x251B2B7F8F85D737,0x1EC3F8D0B4AF1D27,0x76C743579D519B77,0x5D1903E8B4B14B96,0x2AF3B1250BEF9B41,0x1248BF6FA4ACFB47,0xCD660A532E924506,0x8C9713F1D568A44C,0x9F34F4993D97BBA6,0x1774F3F86AB1AF7D,0x49FE5E01124BAE40,0x5C5F9739ACCCC247,0x542DD5749C1CC51C,0x6B2AF4F2AD523BB6,0xC5FB63084D67FDC5,0x7BC97AF866F33EB9,0x3B8DBF1C47C14DA3,0xD8787D44E1C8C8A9,0xBEA8D8E21866B024,0x1261717AD9F4E5A8,0x888641FEAC91C6EC,0xCD71D7DEE805BCF5,0x3ED986E259FDEC11,0xFD8AB784C6B6BF34,0x8A6833FAE6EBBE29,0xB1F78BA4D242F3ED,0xE86A64F4C29B3497,0x8F9D23344C7D4099,0xA8AA5E98883C4AF8,0x20983F2F1779E46D,0x7B5CEDF9B2974402,0x4FA809A6304143BA,0x2DA2EA13E46F4841,0x7D41D05F5AAFD077,0x42F13981A756560E,0x66EC2E000F5CDE98,0x974D633D0DFA4A5B,0x2371AAF1F22E0EDE,0x631BBD425B6B4503,0x4E0812A3C6386FE9,0x953F69FB5544B521,0x114E0F3152C39A42,0x376159A79AAC925D,0x46466A2B8586F23E,0x4A4D8DFBA6F7B43A,0x817B80AA2D39F2C2,0x021012F7794AF038,0x1806CAAC2D5F4DBA,0x37B6467F30F25652,0x3824217655ABFCBA,0xCADDD86CAD833A99,0xD4F6DCCFF3AEA823,0xA1E653CBF0B3C677,0xC3477F76EC29DBD6,0x8652DFFF019E2EF3,0x5995736F82FE420C,0x9D427181A89ABF8F,0xE8127330C702FBCE,0x2CA30F2976DCD451,0xEBD636D5FEA2207E,0x3326581D610C2831,0x256417EF81D984D1,0x919BEC083723952B,0x560F113197725034,0x3028B31539D25BDB,0xDFDF52194436BBA2,0xC8E56D90848BE571,0x7F373F56FBAC5736,0x2893F02B119D2805,0x50A53990C2E50F9B,0x80C53A5C8965FA2C,0x37E099BDEFCA9DC5,0xE4243C71EE618F5C,0xD803E7623A0BD019,0x0B92C6D6785D263C,0x0539AF9F0AF6DC52,0x2047F49458F37FE3,0x125C86181FC6901A,0xAE243277FCF46E9F,0xB10DAA26DCF77107,0x5FC3B62955C2CC29,0x7904D929171CA3BC,0x2F5DBE5F978DEF3B,0x01D0E15923714F5A,0xB2E51E5C79A8CC25,0x76ABE16D711701BE,0x4CC11182106C47E9,0x5F5A7F2252EB18BA,0x0EB4C780B32A20AB,0x0A7C4FD25DDBB79A,0x5B26A82D1697C1D7,0x4B22B2BBFB68D374,0xE01B8D7D054DC98E,0x02A56F7088A79CD6,0xC8706D03F121A892,0xEAC3A0706D913F02,0x418EA9A22731D455,0x98B33774222C28BD,0x5FB87186D32F0759,0xC9D4C38CA9188B85,0xBE1218016490B858,0x4854E55FF95DA971,0x87DF9A7B7347D0AC,0x77EAD35822F3B629,0xE08C022A42002BDA,0x06C24A0C9A2A0D10,0xE61221C090B2143A,0x452445A49F497841,0xF9E915237147D43E,0xE85A467EEF0E2EBB,0x94D39BF70606575F,0xBD8D11BD6DF11172,0x740F3FA9A2437B0E,0x59E9E721AA409A18,0x4F67BFB75603D843,0x7B21927D8AC5E7C2,0x41C714BA9F7E2BCB,0x82224039B0447FDD,0xCA4DF97EC3D89FA4,0x58A37092A18AD5C2,0x7FC0CB65F326D0F1,0x278AE75E948D6246,0x6C2AD7F882AB6080,0x2CFD55532EC1554D,0x0412C7A96A8214D8,0x15A8DE8B61D50CB2,0xDD4E3F820B852ED5,0x7E71CE18B63FB3C7,0xAD2CEA201D8F003D,0xC2E7E97BCFA3F3E0,0xE73671BD1A656FA3,0xC50839215B783453,0xD068765A78FEEC7C,0x855F1C38D228CDA3,0x37A6E24358BA19D5,0xBF3D948BE37554D1,0xA58E1014A4A00161,0xBA6A45356AC83949,0x75B5C1A50BB7B807,0x206913B1FD5F77FE,0xE4FC9EB8BA246983,0xE0AAAF6B0427FFE4,0xAD851A49105423A9,0x1DCEB07DEB847DF6,0x39C73AD846A1F748,0x71705B5457654939,0x1927D7E4277098A9,0x5344616771F508F7,0xCC1644059015CD3C,0xFE49A985994EDC74,0xB3C28B0275DB8BEC,0xF7FFC5E21DDC9B3F,0x51F2E0853520735B,0x9F05725A7F187B97,0x4CE01255C3EB0CD9,0x7A92CCA4953B8EF4,0x183939EEE3350AE9,0x646CCEED6326E4BB,0x822E18762A4E0B79,0x1C49B02CD70903A5,0x1285C0C2438CD1CD,0x609B8E71B2D3A53E,0x7EB196B8E142343E,0x95D0706519DB8035,0x715CEB080FACEBDB,0xA4D14ACE59097154,0x17BBFBA33F7B44F1,0xC61AF2F5FBF2307E,0x356ADF706B9526BC,0x077CD1FA1552A893,0x1C59F8EB6DC241B3,0x958ACEED160AAD72,0x93D75B7A87AE9582,0xF69DBC777CE395AC,0x8AB00DEB937D166C,0x852BC503B76BEE2C,0x16F49A887B34F65B,0xE5CBE892B5EF71FE,0x3D01FD05A4F25C22,0xE6FAFB133CCBB50D,0xA35D51FCD6B4ABAD,0x60A50319C331B14A,0x2C216B79CC6E58AA,0x7033DAD279784F08,0xBEF44E3F1EFCD112,0xFAB3AFD54261F0E5,0xFF4CC7B61ED4D4C4,0xC98036900DD3B2F4,0x782F2B58B1025902,0xB7C892E0DBA3F79D,0x48F16C213FBB91AC,0xAA7CAEFDF0536FD5,0xA376C69C3E347CA8,0xF42B26706C4ABCD4,0x8C63CA5A0E7F8C30,0x3581378BCAD7D137,0x93F5DC0EDABB93A4,0xA79A84A4A54D79E7,0x47E5733F7CB56AEB,0xB4B2F437A2ED089F,0x67188325DED8CE26,0x242C23B9005D99BB,0xCBF6C3C559226D3A,0xFD20350FA63B67BA,0x1C7B7441D9E6C0AD,0x1FAA4CCCC3381E5A,0xD533BF6644D8D890,0x1A608A2953EEC8D4,0xE46F9D3888643306,0x8F358F2C0338B42D,0xE365EBA935444AB8,0xD60F14A00F31BC3D,0xBD0AB2E74F34E6DA,0x1840B189BD5B8B00,0x5A15EAF629370D8A,0x5888AFE25057581A,0xD3BF9AF919A1CAF7,0xC5ABAF3C1CA737FC,0xD5CB335E79944FDA,0x0B0B9D91F98F40E5,0x3E248F08EAE3F0B0,0x9418D65595E0A169,0x39B2A04070AA832E,0xC3F7547425A41FD0,0x7A0582DCA39D503A,0x77B1F215A7C9AC69,0x3B106CCE80CDB8D3,0x20E9B4F1025CAA99,0x4CD1056E6775A775,0x1D2788471DAB6473,0x61D5CFC41ECAD181,0xEE5163F49D567A21,0x54A6658C4D0CB890,0xA6E1A61DD21B58AD,0x5C3A5B32C77272A1,0xACB282A402A80215,0x05FD2151C23474A2,0x03819F9457D505D5,0x49353A8C5D944ACA,0x7B57E9CABB49AD5B,0x98123FE53913D23E,0x2AB427952D86A775,0xF67C0DCBD45F7D12,0x5B0F941F8A494407,0xE381BCB6FB4CFE27,0x5BFDAB2F420F775D,0x1CF25F6002D4C674,0x88186E4950F3417D,0xA914A613ECC0C31E,0xF2DDBD7242D5B4F2,0x22E313C91642D0BB,0x8673A10909246F5C,0xC5D7445A80B94862,0x1ED04A0E0040AFF1,0xD44DCA76A52CE306,0x417F77D52A16985D,0xE74BAD53B8146900,0xA078387647B5B13C,0x0BE24B1E683835CA,0x0CA8845B5072CA28,0x803B83127830752F,0x83A30538990C6373,0x10B5C336E3364AF1,0x77A182A03FDDFB72,0x8111A00F36F88AC5,0x12B1B232F8F93EEA,0xD37FDF46DDB6D9B7,0xD240090BFCF8E531,0x007E1149C96EC0EF,0xC6D9F225477F87C0,0xBF0A30D07D3657D3,0x50F5629643BB8618,0x431E2C7A09BFE59B,0xB37DDD88EE7DBAC0,0xDE70AF4922494403,0x0646EA3AF8B64AD1,0xFCF3EA0CDFD87019,0xA9980BAB55750288,0x7B9366FAFDCA5C18,0x8C4C0C372C4231A8,0x19C449A0570D70C1,0x4863840EE065F31D,0x7A219C41BFC23EBE,0x90BA2A6B26756082,0x76D01C83B490D3D8,0x0023FFCC6F27C675,0x9305A641AACA8F39,0xCA61A7A0E8B6268B,0x6D3928A63561EFB3,0xFA00EEDFBC062F4A,0x68C8F8D78AF67DFD,0xE3BC827EA4C05C11,0xE629B730D5407D52,0x84F82D4627CC0ABE,0x7DC80E25A3D8B3ED,0x4CF182BE7E4EA072,0x54C1CF4228DE83EE,0xD43D14BF1120375F,0x16D1E6BE3450B5C9,0x72681270F7250F8C,0xC3E499D501D07CFB,0x32C1FE529BB54F8D,0x9D5F7C28A13EDD76,0xD99B7A198F77DBBF,0x6BB14C709F18947A,0x1D78C1F0621C483B,0x0D05C661E25A4AEC,0xA06D065731525F55,0x0D37A938722BF295,0xD75FECDEE91133AA,0x4DC9EF479C36EAD8,0x83F6C9F54780490D,0x9E4F53D42D2DDBD4,0xCE371C4BB4C50A39,0x92459241A5DEC446,0xE456136E3BC70DB0,0x3E053D98D5233D09,0xEA04FDC17970556E,0x8B769E8C52BECFCE,0x17DBBABE99C4618F,0x7DD473BB113147FA,0xD0A36894C06FCC96,0xAFA5EE90992588B9,0x229FCAF95DF6F83F,0x8EF287A5AF1D4EAA,0x54C8764A6F44A7DE,0x7E98C6329BA32D57,0xC3A78022099B5D9C,0x18B5BE2AE890DAB0,0xBA2A79538FA5932A,0x822673BAC7782A97,0x8E6C0AFA8579E120,0x8DEAFCF3DD270CED,0x2A801B16EC0D3AAC,0x82183C07C169DC3C,0xA35716DCD581125B,0x7DB6F5C8D0EC3682,0x09401F979B497E8B,0x9F0ED10DF844D36A,0x4FF0A22A4CB2EF90,0x6A813EFB7FEAF843,0x41F8F47959BAF4E1,0x889BBE2CB4511AE9,0x5149401FDDDFDEC9,0x125EBCE5A4CCAE24,0x6EF3036E1944AB00,0x31BD215ADF696B4E,0x25B7E034838EA9C6,0x266E2D14D3F30DB9,0x2360A489FB4251AD,0x61B3EA835FB5593F,0xC16BD75C85544A7E,0xF04A4CA48739B47E,0xA7FA404B1E35189E,0x56754E64CF56D312,0xF8738637B257A103,0x60A243E279597330,0x89F292660F625FA7,0x2AF3F74637BF5607,0xDC87B7C51DD312B9,0x0D6235C0C93B3F91,0x952CD1CE4109BD7A,0x06F761CD2158BA12,0xEB5E4A4A3E00DC6A,0x1EA3234BD1D00168,0xCE708094E5952534,0x4995A5E0DFC611CD,0x56D264F39B05AC1E,0x979775D97C439EFA,0xF391481C70DCAD23,0xDBBA959165CF3B0D,0x559D3A55F398A0E5,0xF1636E069A3FF835,0x5C99CC3F61FFF04B,0x1A8F222E4DC478B5,0x9A24703A622AE2A0,0x1AA585D463FF5334,0x9C3558A444C967CA,0x51514DF30319C2F1,0x0AB64CEC959E2218,0x7CB415AD4308EC3E,0x6A5417E661E0A80F,0xFBE1A4CF1C22F9FA,0x2AF873E062B25EEA,0x3F2482B497897F2C,0x84F447BE69C588CD,0x6DF00A102B439EDB,0x9DB610096D2B7AB1,0x18F8F243553B3EAC,0x2227663D99C343B5,0x529CF57CF51E1638,0x2EEAA0A466002C4E,0x06279D1DC3334C5C,0x85A3C3D5C3CAA70C,0xC6821A3EDCF9DD19,0x8E5ED4AB050A5C5D,0xBC3DCBC1D136FB58,0x17F742B3D024AB13,0x525585E874A22681,0x47D99D1AEB8FB965,0x554FEA35033B32F3,0x0279E442787E8939,0x3FA7B7F94F124D5F,0xBB52B463697E0974,0x0750B366D51C28F0,0x7881A856A7EF903E,0xF11368631E8A0FAA,0x62E5BC8951E3DC91,0xEB697388BA819BE3,0xB294562495208B3A,0x193CAE9E558194CA,0x323346F289B7E6C6,0xEDDD4C107F8F28F1,0xD439CA768D48D62A,0xC2A1A5EBDD40502D,0x4B7622B29914F7BF,0x07AF248ED4BC3E2E,0x105EFD5C9E6FF787,0x77365723D2F482F4,0x34EABEA119F58C2E,0x9C6F800E8D037875,0x3E1D3C820DCCBB60,0x89F01F86EDD70548,0x835F9270D77F195B,0xDD669626345CC215,0x3A995FDC5F98BC6C,0xB930E85C72391D28,0xF262EE05C278031E,0x6FB65A5700BC10E0,0x8E4200F8380CA61A,0x213EED11AFC18A33,0xBEB35FCE096F60CD,0x71A761164E467452,0xE0192901545DCAAB,0x8E794D6BB0620C08,0x64F30DE074F60D66,0x871FCDEFFD666F1B,0x7672802BE10A8632,0x7BF1C288354AE2AD,0x31E2751DFC704D42,0x24AC1A05BBA66C69,0x220069C46FDD0B7D,0x96FCD3F8A5ACD9B7,0xFB30444D1C7064C5,0xB294CB45FBAEDF36,0xF5E70925E13B781E,0xDD1B76EF91F61FAB,0xA222142651487912,0x21D9D9F67AC2314D,0x16B2637A820EA7C1,0x35A10C21316C50B3,0x6042BB052E06F199,0xC0215C3A9ADB5722,0x45DD76A25F6ACB91,0xF2F0660C47168C06,0xB485FBEF6CFBEDBA,0xFE45F141E8FDAA2C,0xAE3D9CB9BE415FA5,0x7E3B50039C2C4D6F,0xF1276F65248BCEE8,0x51B6A5CDCB64EA8E,0xDFD1199688F556CE,0x48E2279EAD2EE385,0x1CBC3607C42735E4,0xC9AA6FEB5B5419B4,0xE54A58AE6A009CD9,0x31C7C924832BFC5E,0x1BAD491ED399FEAE,0xD416045FA2DC8BDE,0x64CB5B9190787CDD,0xB0088FE670436DE3,0x2BBEF53A773FC28B,0x0FE9ACDCBF2456FB,0xA724A4276DB15DBB,0x9E27FB3407D4B6AD,0xB701DC40CC6B19FE,0x8FA32B67525B0FA0,0xF36A3CEF6E3357A2,0x1156531A022B9A51,0x29C8804F290E6642,0x232C25BD92ED536C,0xA012444CA0FADCF8,0x111DA74478D641DF,0x54AC556E974FC80F,0x83DB86C87D8C300A,0xF56D58C7EA56FDA3,0x96CDB005038E6CFB,0x67A3117159B90D5A,0xA0F6768F11DF4886,0xB649E4A641DD9404,0x5DDAF05E2791CF6C,0xB35E38480F9F7193,0xB2E2A0EC290554CD,0x4A72977590110DB8,0x16852F92C3C4A19C,0x9B638D6F00212BA8,0x959DA5F4BD679CC2,0x36860283911CAA1F,0xC99FFB99C1FAB3C0,0xDCCCDD086F6B08AE,0xB9A34954258DF45B,0x6C3B32FB2B327C84,0x45F07709CAAAB997,0xE508944078BF2AEB,0x6A4D752E911C2508,0x83AB7401F9A8019A,0x8A5C07FB2738C848,0x02DE68105221663F,0x9A7B8686ED4545FD,0xF2ED4998E3C3714E,0xF0EFF7F1E716FEE7,0x9F2DDBF8810029EF,0xB370E3FDB73DE41C,0x04248C4DDF577030,0xB977B9F3E20DFF66,0x87CDDB7706F3B9B9,0xEAE2F7D0686BF973,0x24C0609C7532AE99,0xECC2A636D751957A,0x3D8C27C2D2867BA9,0x5F5103CEFC0928BE,0x72B23C85EEC5A33D,0xB945A17E0822E504,0x20D20DA3854E7F06,0x83530643B3FBD58D,0x35CD39517F10C5FC,0x1CE649FB33164D82,0x49BFEA874E726E5A,0xA3F214EBF7D59AC4,0x2321B06B2812974F,0xB5FFCB57FFA844CE,0xC1FBD819B9A2582D,0x0ACB7F63BA215E1E,0xD38C642A6CB39B44,0x51C26319D431F615,0xF88B549BB6771738,0x61A08BA8F91F073D,0xB180CB120253469C,0x539AABD6E3468AAE,0xB8FEAADE6EA275FE,0xC62C526119AA127C,0xEA874C8AA05EFDC0,0xC26D8888A994D256,0xDC79D75B1F18D938,0x40CD959B3B0F685D,0xC04D8CB70EE05A82,0xA42C395046D5957C,0x7AC2EB737290A101,0x6B206857F2348023,0x8F2A7EC498E1479A,0x37487AADD61CCB91,0xF9195856CF63C18B,0x87D895FBFF509EEA,0x19BFE768EEE230DA,0x442F79C543E0395F,0xE9DDFBBE214EBE68,0x61953819ADD5D922,0xDF21C1D1CF7B7B6E,0x42C6521A9B09221C,0x52A508CC4BD72B4A,0xA8BDF59DE88138F4,0xD40D2DC9F33D6750,0xEED08F17855FF19B,0xCC45BE0C0DFC6304,0x086B0F6BEA36AC91,0xC63207EF8EBBFDF3,0xEDB2AF85C5E3D020,0x1249A948F98321F8,0xC9D82B17336478C9,0x20BA43F6894295D6,0xE07CBFB8D7575DD7,0x721384C1567F483D,0x05DFBF3AF3645F0D,0xAF053023BD52F989,0x85C8641CEE4275E9,0x616B8EE4B77DC979,0x6EF88F3AABEA5C4B,0x92957BF6E630F19D,0xE64C68EC1ED4F233,0x6916E2489B75310C,0x5742E30BFAEF58A2,0x28754576672B33C4,0xFF8FB3F4413F5872,0x8ACD333F549F82A2,0x018EE00CA458A6BC,0xB4927213BB3A2180,0x026E1EB9752C8687,0x8896DE07FC0951C5,0x6F76A7C45E830340,0xBCEAA4BD2B090D12,0x79F50312690DE361,0x5D3C6F15997C4922,0x784278151E0ABD14,0x2BF75FE878F3EC1D,0x974E7E329BEABC1D,0x1A27D8FA28A1D194,0x92CECE1FB9759007,0x957214F7193D9BF3,0xE81E9FEE64B501C4,0x8627981D4336CBA6,0xD919D9560D6494D3,0x936A149EE4EB0D97,0xF4F1BBA7D7313F5F,0x883802F7C6FE9DC8,0x9E1649A5A2DC028A,0xC71CE4B48A6D8F28,0xFA198EB5FC989255,0x627A9B1BEE218CB7,0x9B249087629E8E59,0xBE38BFDE177A99D0,0x8CAFC2655E818A16,0xAD9C9A1791ECBBD7,0x1A8DCD0454C53C0E,0x86FC2239839D4781,0xF9944B9C9CC4EBE8,0x8D8A99E3ED1732AF,0x866D5AC62D9B75FD,0x6C5CC00578126E5E,0x83F969297EEF0828,0x419DD6EB2EEC462C,0xCC225508D53C6778,0xA237F5745FDD8B44,0x56A6EC7859DD63E9,0x8148438CA9B7B222,0x47D50194B132CCB0,0xF3C8FE29F984AF2B,0x118C6BCA3B5530A0,0xE89CB4CEB7FFECB2,0x954D8F1E3A057213,0x77B7CC3EECDC3758,0x07ED3A80CB051665,0xAB94BFA59DC043EF,0x2F251A16360A369F,0x38DFE3BB6ED9C12F,0x4B287D3C6A9F1B1A,0x565E304EFFB1B2D3,0x6EF57CF49E671C4E,0x7C9C6E7E0C9054E7,0x4ACB6CD94E1E761B,0xBD5C81137BB3DF98,0x89013D2097DC59B5,0xF3B340A9971B1103,0x1D9D42C4ACE78217,0xA34385B8B5D0DBBE,0xAC65183B912C80C4,0x3BC3007364AF09CA,0xAFAC1B6F9C0E4C48,0x0B316CA41F442FC2,0x4435870C946504E3,0xC4CFFF452F974608,0xF0AAE9B0A7D37615,0x4D55BB7C31697629,0x2475D79B80403E16,0x96F694AB398C7F3F,0x9F5AFB935846FEC7,0x526CBF6BBDA168DC,0xA7C1EA52E3DCD380,0x9D40B8879EC15824,0x15B732495B8DA450,0xDD34C1415AC80088,0x73DAA3001311C006,0xCA3135C75CAF3638,0x1DB457FAEA30F622,0x5AD9A9F8D6C6CE50,0x69D7FBCD962A778F,0x403D0D99919A850C,0x44104453153D77AA,0x8C72B99A98AEB66C,0x591932EDC0105974,0x80D6D70898EEF931,0xBC5FFB930875F041,0x9B637A10F87DD333,0xF4B9AAD618D6F621,0x50FA565202556D60,0x6F178103FF5A5148,0xF8264BA0CA28AAA2,0x55453794236078B6,0xCE4D9467477744B8,0x73B591BFDBFFBC23,0xE60D1A5C95308732,0x42A8E8C171DBC798,0x7B4BE92A6962369E,0x25FE5FCEF113F8C1,0x03FAAC5FFFC44336,0x01FD15A8ECB593D4,0x7BE44432F978AD4C,0xE00BF1CA62D5B733,0x675775CFD2BECEE4,0x7680A062A9FAE37E,0x1A2C2A0561A2EB83,0xB1E02468220BBAA7,0xE769CF930CBB1090,0x509565ADE5BAA4B6,0x32CF0D9CCBCE9061,0x6594BD70727A3C53,0x685D2F5E96B9349C,0xF203BC6C17B18AA0,0x3E97B8275303D56B,0x94609885890FEFBA,0x6FF39AE54317ACC8,0xB52AF214C039236B,0x17DA0EEE2EA2CE1B,0x49D72224A1F6AD40,0xC480A076D7D6EE5E,0xDB18B5CB0B37491D,0x8C8D3363041F0F91,0x741426A49E6A9C10,0x7D161E2491284A41,0x1D28AF57941F463A,0xBCF28201A293DF36,0x237608F05A6AED6B,0xF0F769BEEBB189EE,0xD377D37068A92F85,0xEC623B6B4CA6AF2F,0xD163B1A12E37B181,0x0583462619377E53,0x7A203F01D75DDCDB,0xB6082F12AD1E9A66,0x8E372291756DB23F,0x374EF19C9DE0CD95,0xA55367FFB723B205,0xFEBE786E25C41C03,0x26B9F2C90ACF004F,0x7F29EE8AB575D5EC,0xA303F4FBE5EC18B0,0x64CDC3901043D16C,0xB91505F0590BC001,0xDF0F191F602DBD57,0x4909CAAB1BF9D3DE,0xBE70751703477E24,0xE17868B546BAB72B,0xE899D9AE2E24BCBA,0x2AF4626001102715,0x203E2ED121EDE953,0xB36D8794E5C607B7,0x7C703E687E9D883E,0x147A291E5FD21F0E,0xB0EEB34A3D31B456,0x9FA6B3E9352AEACD,0x9DB7C7149472C055,0xF8B60845F6872FF9,0xCB53F9EDA784BD9B,0x3FD48F13F398824F,0x8DB177BAE5FA0663,0xB5A195F62277880A,0x1D39FC6774092B91,0x64068BD86B81F5F0,0x878F3C986CAEB450,0x7C9C8531D016CF17,0xFFD9A2537AF8CCC1,0x8F1D93C8C0AF6C98,0x17517F70887F5C55,0x1D5339B7116631EF,0x66262F3E43C6B60A,0x431185DBFCAA57FA,0x9488F6AC6CB37BBB,0xC2C48588BF00D774,0xF00F621F6AD97F51,0x87810A68B26C120A,0xBA681C9C773EA348,0x4CEB3A604544974A,0xC196D38270915CA0,0xA2D49E0611E0036A,0xA675D27FA999594D,0x5E535B441C567DFC,0x531DCF41818A541A,0xF9AD30785102EEE8,0x7A24D93998BD8282,0x55945C13330CFD9F,0x4B848D8D464ABABC,0x960CE9E5F180C77D,0x8F89B1D9967ADAA4,0xB37383FD76375DE2,0xDE9E180056D21D7F,0x917468EC1EA9DAC6,0x55C3E7436B791F83,0xD7C4ED946705B20C,0x693B6D43D1E4D7F1,0x0ABD137403769F19,0xB39C93C5E991DAFB,0xC7BAF415E323C5E2,0x6010C2E66C80A008,0xF3484EBEC699D644,0x6C9A1EADEC0820A1,0xFC70692EEC293C67,0xAA74EDFF6D754A37,0xE1F6B4AA3D5443DB,0x6A95117D7690CAE4,0x66347EBF465FD72C,0xC295B490920B27C7,0x07C40FB8DD6BD090,0x693ABD3BC2D6877C,0x5E0B58D3B8288234,0x0C8A89B937459E85,0xF5BAB7403E8E7688,0xE7E597189F9F9929,0xF8FB295DA9A88E20,0xE5DEA135BC714059,0xEC0A85A34835219E,0xCD139F09F0504D33,0x3F16395B55376EFA,0x37F00AD632FE517B,0x6969D11D4F7CD4E2,0x1C2D2314C3178C7A,0x052F2A166CA256FD,0x20959063908C8324,0x9B5CD100B1A70D0A,0xB1C3552D01462401,0xCE7FA1EC07AB9107,0x4DA63DA6B2FE8F66,0xB8D57D22CCB51D0B,0xB82EBBD624AE9E81,0x60438B53EB8C619A,0xF3A24C8E970CA163,0x344482662DA133DA,0x847E90098DB47064,0x3D525B144C6DC903,0xD9BC3C7CC60A4457,0x9D175CCB03350631,0xB664EAEDA08A3768,0xFABA36636F996C5D,0x2900467DD62AE597,0x07842C01922E0159,0xE774DFF4CC4F5496,0xA9E7F0C83EF67BF0,0xAC0D527CF61E2239,0x56CA98E4A6B1DC09,0x6D5FC207CB4D1441,0x8C5C9573AD2CBBC2,0x4C84222CED1AEBFD,0xE6299E5EB05E71C7,0x71220A4B65BAA957,0x351A02AB302941E5,0x1F7FA0DCBB8EFD80,0x8E140AFC555C50E7,0x871B4E8489EBE508,0x05498B0FF3CB0E11,0xE9AAEB7F4748CACE,0xFD546D233900A3F3,0xC3426CD55F158E88,0x958C94AEB5A79DA1,0x18BDFC9155E15C03,0xEC2A7659467307E4,0x9AF2721663847E75,0xBBE7746146F5E91D,0x7BE818B0BDD5EBC0,0xBFE9AC6F5E01A811,0x8C6C91D2988D3136,0x0C66DDF4C0D55C55,0x13C85C677E8B6D25,0x73E1E21932B7107A,0x031CDFE7FD5A457E,0x8DDF52E8F026CBBC,0xF355E6665360EA24,0xD6EAE92030169B61,0xB901DC85B10421A9,0x802FEF8F1BAAA53C,0xA9F5F56637C081CE,0xDA0DB21A6FD30D70,0x9D0953F3F39DFECB,0x7A89FAFE8BCCA159,0x87B9797C0BF781D3,0x6D187332219A78EE,0x5DF3323937A2EE1B,0xEF7E4B605B52E72A,0xB85612579F6EC760,0xD8FCB3F60F67D70D,0x1E16F5721F9153C2,0xE2680CD73EFC24AE,0x8F63257F19842D5E,0x5E57BD411C30125A,0x04BF01712D980191,0x5821C06A75C90D32,0xFD71D2A6F18EB91E,0x34250228B6F91406,0x092B38AB603F9185,0xEA164A21D698D56C,0x610A860849177ED0,0x2ED5BA9B3AD42A00,0x3996BCFFFE71C493,0x060776E09A7B744F,0x1FF7AB6D3430D200,0x4CDC0E8806BE095E,0x4EA301B95E9BC0A5,0x2A91ED6EE3D4EC5D,0x184F64A57C3F8957,0xA683CCD550A2BE9E,0x38E6EF1128B98D6A,0x724632BB9F95FB07,0x330E0F42C0A3BEF8,0xCAEC86349C7E9313,0x3E322587CC3646EC,0x97180F189F7CBD7B,0xDB22E16B5A456251,0xC0AFFDDEA732E0E3,0x1F917C5563915A96,0x9D1DD4FD64D27BA5,0xA92185338F458999,0xD5DC609A094E21B6,0x038A5EEB5A87F6B8,0x8E07824C424A8663,0xC64F1A6F788A499E,0x353376302DA5C7C5,0x93469B61A518A098,0xBEE70318113C768F,0x78C265521F4520D2,0x5698107F553D48F0,0x4A3DEA9CF9729E3F,0x23A69168AE9D996E,0x6A50CC57D443C00D,0xE06A4FFB9654F5FC,0x6C58A659973918AE,0xC8D005BA0B90930D,0xF736F70A8F395321,0x9715483892451A3D,0x9AFE096C8ABE6114,0xF191657B67CD3979,0xA421D0BD60BC8866,0xA20A42F996567C1F,0xA161EF4A6E754FED,0x4ECF1CCA66E48DCD,0x45FEA4D5CAD2DFB4,0xD84487C6A0DC3DFC,0xAF2E8F5A9F0F2680,0xED73578C05E13EB3,0x694B2CCBFE4F7E3B,0xB95011D077CEF75D,0xE576379EA964612B,0xA545004986C475E8,0x8193FF6DCBD95608,0x0C81C1732698C35C,0xDD2B8E1C12760B91,0x146E693828E610E6,0x2EA20F2E9F611236,0xDE30806BD3B396B5,0x35B03062353558DC,0x3BD39B810EDB7152,0x220A4C176309868C,0x3C32C8C278AE9766,0x461F9F533492B1A9,0x491FA7636ADDAA79,0x742E9BF5602B50C0,0x84A9A0B1FD5DFA50,0x59747722D3D9CE38,0xA9DDDE53C1F1ACFA,0xC3F38DBF8F0A23B7,0x3D09A7DA2F046CFE,0x4E37EA6239141167,0xBBA2B1831E2A36F2,0x71446498F53A7B2B,0x5683F314C6FEE0D1,0xF11C4935901F0ECB,0x8524A6AF94EA80AA,0x0B40A411AF4A0CDD,0x9BCC6123DC7EECE0,0x15EE31F5E371744E,0xE9AEF4A8611C411F,0x447B980966555C87,0x443CAB85E097BD58,0xB016E7A7C2215009,0xAA53107B6D6C632B,0x75FDB3A481C3F175,0x7A45A763CEB6DC21,0x3F5AC77E47036998,0xD26DAE7036DF84DB,0x36E9BBB2A39577E5,0xEA58D0AB4510F165,0x4C9F1D2DD0A827AD,0x277F66E34C63084D,0x10354E85842ABCA5,0x97846F022D040BD8,0xCD13F92866F650A1,0x4EDFE12E8EE39861,0x131214C31D905824,0x4D615E425A9164E0,0xB206EEC534006609,0xA7EC284AD7108A76,0xA95054F04D6D3E6B,0xC007C276555A89CC,0xD408E86FAA161C85,0x55C3D05971D2824D,0x21E3B7972D9E3735,0x820D69221A962E3A,0x9469A7D0366E9148,0x4102DA68AB54F81E,0xD348EDE9B8880BB1,0x0CC7EB8EA1878D16,0xC4E50BD6B010620E,0x2792D7FAA7D5A4A5,0x8318BDD31FA742BD,0x7BEBD366AE32752E,0x722195AA27409D69,0x3AAEEF2A183DADE0,0xB9E346740915DD10,0x57B10B056D060896,0x79112B7AA6390269,0x63A9AE1788B5C48D,0x360C4B7C40D43F2D,0x5DF5F2445C1A82FA,0xDF410F67733797F6,0x48957B884ED9C8DA,0x788DE3A87909A8CB,0x6C59AEE09A504108,0xB75B89AAACF70554,0x6D160938FEEEC0B2,0x8FDE3F352CCBEDF1,0x425A335E5661CC79,0x01010AB0E18D4C63,0x78C07E72D0DCE523,0x0ACF8FB26DEACC5D,0x892C2BF83C72DFCF,0xB96778787B27BD3F,0x935749496AD320E7,0xE38C188A7A0FD2B7,0xA9FB645A872196E2,0x3B9D10C36165C616,0x62EBD40168398AA3,0x0D872B006BEE5879,0x4AE2A748438CBF82,0x4EEB9316A55E04E0,0x63F1D7C53F549719,0x0DC4E9D772FE8A3F,0x0CFFE9FF4E148B34,0x48B4808242D1C71D,0x315350991D984F40,0x243FD95C513F9457,0x8AF32FE68E6B910F,0xB846699C5855CD21,0xD73F4765933CB292,0x04DBC46AB0716813,0xAEB0B21324FBA069,0x602FFF5F07A318F7,0x3D74ADF78B543380,0x44C8329FB260D232,0x5596D393792F7377,0x0EF40A92CDBACADE,0x9BAE765E870473E2,0xE44C0265307BEE74,0x2A0172B0B6A14982,0x3B1077AC7E7BAAC0,0xB8A4C1F4B06788E7,0xC179483730FBDA64,0x7315508DE7CFC524,0xC9B0A3C225E1FA61,0x2C6A2DCDC8591EC8,0x57A4DE42717B485C,0x513B670F94EC63F6,0x9B2390E5D030F81E,0x9D7669C73A0DFFD0,0x6A522E3A55491393,0xB7B16B1817C6AFA2,0xA936DD2743E59A47,0xEB901A541C2F69DC,0x26674AAD87F75182,0x88E6F696E4A95D2A,0x6B4935CBA4F9159E,0x492216C56DE2AD19,0x8D12A6D3BCE577D0,0x9C55CC4486C95F6B,0x72C71AEF14026F55,0x694B671750C2DFF5,0x194FD7086B4FAB29,0x43A3CDDE5D9F55B1,0xB10156A6537BA4D8,0x3391AA7AA28864B4,0x067C48B5F00B1334,0xDAF97441E1E17721,0x1FC6C708941B0230,0x2729767D18249843,0x85DEB307048D9763,0x1224C2BB53B011B1,0x47CF0003C14AAC23,0x65CF6B81271F3364,0xDC4A294C2453804B,0x7064C2634DE49C93,0xDF44CB335A1ECE32,0x4F1E940E833F083F,0xA087D6CB27CD98DC,0xFE114B698FF86AC4,0x5B00E9540654B690,0x679793386F0AC104,0x59C9605A12ED9AB7,0x4CAD759DE595666C,0x069283EAB7226B34,0x9164B833EA274EDE,0x252A3C606811518D,0x2DE4AF43D7DD69C0,0xA599B1D828912E44,0x858C718859616380,0x4E8243E280119DD3,0x225B20B731388CD1,0x4CF3F98D68D57752,0xB1BD863F686A343D,0x3353B856AF3E8505,0xF23FF7AA4F0BF5B5,0x652CB522C5ED38F7,0x3F804639C8DE398B,0x9E79DCEDF2555634,0x18A4C46343F830E9,0xC60B37E3C85EBB0F,0x65BD9EF1990A2F7F,0xA539A3DB43BD566E,0x617F1A4C450EFB04,0x60A25D10EC697DF0,0xA56CF8500772AAE5,0x82ED72968905E8C0,0x9753470339E5484F,0x729ABDD769C82F26,0xC8B70AD2A8AE2B28,0x07E4A9FC92950BE1,0x7DCBF4F6315CE720,0xB35A3239934AD3A9,0x1EA8E54E2071D62F,0x3F4750E4221B408B,0x1E395EF9D12B99E2,0xE9D83EC3339088D1,0x00AA2EDDB07CBCA2,0x8B4FA0668A756841,0xEE4BB7DC69BCBA27,0xCB7A02E219F4A4B3,0x7B1CD910AB880C5E,0x92A16832FD1A4E95,0xDB0180762842D5F6,0xD60D72E6FB204128,0xE0B7B0740708CA83,0xAA056311128107C6,0xE758CC4FDFEAF97C,0x85D24DEF137E33ED,0x9EEA45F2A11D256E,0x45E76D65FB504DD5,0x471270B73551BD57,0xD0859024A1957C12,0x9DEC9297C554CD7F,0x053FADEDE538C9FC,0xCEEA5ABDF65A0280,0x02486A122EF381DD,0xB61AD61A984BA0FD,0x2FEFCDBD36FCE123,0xA33EC6DB9235782F,0xD09531D5E2B7A9CF,0x7496F21B8CC030D5,0x74FB19789E14091A,0xB65AC2ED1A2CA89C,0xB00C022C24FB3327,0x8D40BBAB2ED7E7B2,0x024A7A0736DA1EB2,0x04A486742D10882C,0x67A3E1405A9B812E,0xF7712CC3C3E4FB1D,0xFCDA510B614FD4FC,0x3D0DA849BB1A52FE,0x260DFE8EFC57B094,0x14EDB882EB2B61A8,0x4500C8B1979301DC,0x6D2451DD169747BA,0xBC77F972BE21C00A,0xA027DE738098B6AD,0x93C9F70E6885737F,0x023C5158B0487AC7,0x86A87C44320172D7,0x284F1778AB8CD440,0xA2D86D088527C541,0xDCEFC76EDB977A15,0x0F8C4AC932C88BD1,0x47E72E54564160D1,0x99F9994D65D7D4AE,0x3970839A4324F739,0x46036060FFEF4437,0x7C2EB4D5E98640CD,0x370910DFF70F946A,0x8CDC11DCEACD46DC,0x7AB04CE8161EFE9D,0xEAC3BA9472501E0D,0xD59B19032C01F58F,0x9CDA29F81CBE3D50,0x74605E9B2F71D3EE,0x214F5DA9C10A3A0C,0x945AE27D5F67D151,0xA7A41D40C125EC94,0x3A2C581CB957DFC0,0xCDA9440805FD300E,0xC1159578B093E792,0x6B1D311EBE16FD44,0x3D490F74417013C8,0xA28EE3227667FE8C,0xE1AA1CB3372400AF,0x7F15EF3466DB298A,0x6B9B933E9D11EBC6,0xD2B2D4075C666B4D,0x32D2F33551DC71EB,0x2D745B9B126584DC,0xDC029B68EB8072A3,0xC6391EA3C04EEB45,0xEB9722493178C956,0xDA9785C9E6749164,0x7FA401D927F226DB,0xB706921CE2AF7DE0,0x6E2D165259EEA0D1,0xED7630745E1315C1,0xDF21445B92F719A6,0xDE57B4BD8EC0BF63,0x45E38801225A94BB,0x4946BB46C5143511,0x0B13313975D97DB1,0xBC739CBA5EAFD73B,0x96DA10072F05CC40,0x631A93E6C7AEB736,0xB8DCD17ADE97FCEB,0xF9B8C63329B683B2,0xBE95DE735C24344C,0xD10A98CB2DECFBF4,0x5A516001E9179A2F,0x32D7FCEE61B35549,0x235D1BACD9510CE0,0x0CB9AC4997DF45D5,0xAE269E3E4786AFBA,0x4C21B38C4B9A1655,0x83D1044B117D3137,0x63C809ACA66E22B0,0x9BCE455C6C7CF544,0x0EF67ED24F6ED2FA,0xA078573E43AB2AAA,0x33AB74F82678B209,0x994052AFD33139AC,0x8D62576CB762BFA8,0x527F6A344282B99B,0xA66305784814D699,0x891EEB5D03E40784,0xF3939F801C9C4B2E,0x56C60D8C9494DE2A,0x37C3E2699300243F,0x86D05001B2079DAC,0x8927CF74C043F6B2,0x050C553D982DA783,0x4A8CA7D0FE3BA89D,0x04EC32C8E57DAB56,0x1A439D6E175B584F,0x9BD4973A764FB965,0x744CCE8D782BB4CF,0x96000A964D2C1C4A,0x9B95BE6BD8867065,0xEEA3382280288803,0xA4DB760DE922F9A1,0x6BBC5367F504B437,0x4F6267305E95CEE7,0x44D39239913FF620,0xE761373ED91CC756,0xFD0B2AD242E3B30F,0xA13A77CD002F843B,0x3774883894755FBB,0x3D3657B3DE6AE8E8,0xD002BBEDE9990FE6,0xBE4C104442AC3C3D,0xDD8F98F89C21178F,0x3397107DF294DB75,0xA76DC3DB904A8ECD,0xCB8F97F7CF64B71C,0xA817F5E6E9ADB5B9,0x99CF59B3FB4EF9D6,0x42359B063BAD6D57,0xAFF9B984AD8A821C,0xFCDA332A125562EF,0x7BD658725742E6BA,0xA198A6358EAEE33C,0x1E52C9224BAEFF1B,0x46121BF8A778AB4F,0x8EC8906474DB04F3,0x77F40DCA342565A0,0x58FBAE9F5271BBD0,0x6C353C97191CB525,0x5F6CC8EB6453ABC1,0x358E6EB513E84490,0x3914B5CD7E6ED62B,0xD1F669C584F9AE5E,0x7C66E85835478F38,0x3E02C4A936908725,0x769581D2CA339803,0x148FE1674C8308F6,0x58A5449B3B7DDDC2,0xCDE6CD009EFA79E0,0xCFE64EED026E7E18,0x6459F3AC53072811,0xABA73129531CFBC6,0x87DD5301967FE014,0xA5A206CCCEE7DF6A,0xA0E0FCE50FE75EA1,0x089442859225DD9F,0x6FE6A4CE7032D663,0x28EFE7DB874EFD61,0x50834117F4E17EF6,0x518BE6D6E3219267,0x89DEFFFC20CED55A,0xB03937AA0F113E6A,0xC929CFFED523437E,0xFA55E94C5B33B7CF,0x50213CB6A90BBAA4,0x27D38CC41EE2F142,0xC5550403A12D8DBE,0xB0E7FC07341138C0,0xBB26C158546DB77A,0x551230D908EDAE50,0x6DF509819CD37423,0xDBC5E0B245D31292,0xB20ECD5B00761497,0xB4500609B24A67BF,0x8BC480D78BCB7865,0x213F2E800582EE9B,0xAC970D750F6CAF72,0x67C1CFFAC0B092F0,0xB45EA5DFF9099E0F,0xA9A40B94E60CA41D,0xC8BC99A87DC490BC,0x59CB4B3F28B0DE78,0xAF7C483417C9D807,0x9B08C496C2C04408,0x11848449FEE0EEDA,0xE5AAEF10AB8E5402,0x55904FAB3BBBCD54,0x68C3139AF1DE9065,0x76E7F5E24FD7EC5E,0x46CF2E048C21FFE6,0x47AF35B90F9C4CA5,0x0EB5CFF714910236,0x807EDFCA39DB85EC,0x7337595BCF670A70,0xDD6035E2C72EFBF9,0x28E555C4A561A493,0x0DA1FFC782E480D2,0x84EFBCAB82524B04,0xFD168E858C4041F2,0x6C31A13C4D78C6F3,0x0A4D038F533C4E9F,0xA3250C7245545473,0xCADE19871FE41462,0xC04D0A861A5615D5,0x0376E4F9D5592BA3,0xD1F6F9393BCB349D,0x4028048BEC109A43,0x1DC17D550FC48C56,0xB4F88471D39FCF6C,0xA45A9F542786BCA1,0x870F5BDFE5CF3B0C,0xB36C66FA0D1200FF,0xB07A09DA23B7A2B1,0xA988C37F558446B1,0xA0A2BB377051EBB4,0x4E553A3A9AF8D298,0xFD69619B3A922F0A,0xC2DFC2A5F29FC7DF,0x341513EEC4180C00,0x145DA1115F5D3B1F,0x3569D3B4B044AC55,0xA8D21DE05D80E445,0x00D9CC44E9F347E1,0x5851E6291AF42C3B,0x459CDD11165DBFCA,0x23C72B088B51490C,0x35442BC4C26DC5EE,0xD0301F69BD07B85B,0xD87285C59DF3D449,0x86AFBDC3CDF0E427,0x42E29E02E0AC0B40,0xC8CCE05BA843EBD2,0x57F7F28EE1C4D923,0x15D53D9F957BEC7E,0xBC76F7F55439BBEB,0x0FE0A5BFE7859826,0x7C3647BB738281AE,0xC0519B87125F3B44,0xB712CBE0A9F642D7,0xE10D5C76A7D3474B,0x29BC01354AE2E262,0x8D54F62D0401B61E,0x667517F456902A70,0x29778675A95F7643,0xA5B573EE94D5A0E1,0xC19C458B0FF6C3DC,0x2C2456109E4666B6,0x7F41554170779BF9,0x7358316E5AEDD0F7,0x1762D11298B8A55D,0x44479514B2F6A8EB,0x9B5CBB99C4B8B58C,0x0054E6C20AA42157,0x193F7EF5DAE04987,0x754BEC7930104AEA,0xBC3D7C0723188015,0x380BC31CF789A6B9,0xBC63D62F239DFBAC,0x35B191C130A64AF0,0xA97F1C2355A72892,0x0AD8647E9346F74E,0xF6526F558A71ED40,0x4077559ECFFA34A2,0x3BD6C01581B367AB,0xF8CD39CA248C95B4,0xC6677A41EE0158D3,0xAF27723A5771E64D,0x6F8E122B2E16D97B,0xEC33331FDC461D37,0x6AD05A6E99A27D6A,0x40B4590A22376C6E,0xCD6D45B8708847E9,0x694CC5A02186E30B,0xFA1320529DFB2DBB,0x0198749E514C7CA6,0xC89E87A8DED7EA11,0x324437A50BB5E093,0xD6EECE66528147A9,0xFB14DDED4934B245,0x0FCDCDA82B5AEA6A,0xDCCABB1409432602,0x808A9B41FE95CD49,0x82F0879991925B44,0x6E7C9A5B0FA75086,0xA9547A728D3166D6,0x2DB5C689819D4D79,0x461EDB9C0544AA9E,0x5FB7233D70A153BE,0xD8145EA37482CDC6,0x4954C2A35A807271,0xFCAE57B947EB4000,0xA837D94EC75395D2,0x386E5D4F5D849F3B,0x3BDD410C2966456E,0x90ABA4E04C384655,0x79E7CD34B2FB9D13,0x9368190599AC5ED3,0x609C3518C580175F,0x7D6A6758459F7C3E,0x71D21926B98A57E6,0xC5FD9CDBD6BB5A86,0xEB4DA451114F6814,0x4680B51A9BD94CFC,0xDAD8CC78DAB6EA0F,0x758404C84DFEBA82,0x8BCADE07AF564320,0x2E73B78BBADF8CAF,0x82E6BDA5FD47600F,0x7038EB8FEA92E750,0xB28FC7BDB428EC91,0x39D12C7BD8A89248,0x181FA3DD088E2FA9,0xC562422FA421ED93,0x9F6A30FECFE2A1E0,0xBCE1F7DEB95CC29C,0xAE851B8F8E93E92A,0x3BA65E3FD360D766,0x01CCC45FD14B2D88,0x1FECFF2E52D97862,0x67A9D1770BFD0A85,0x8B6A88A307256095,0xF05443D747CFAF70,0x27FF15E34E9C28A7,0x9759717E30CC8F0B,0xBFAFA0BD55CD1DFE,0xCC97060ECEC352F3,0x5786BFAF097205D2,0x89AB0DFC7701C17A,0x15E0269C83408064,0x3C8F895C07F800C8,0x6F040DFF13112442,0x00F82DEC441D67EC,0x88CB5CC418CEC250,0x3D022510557F2A1A,0xEBE8963099682D22,0x004F754D5153346F,0xB09379556A657DE1,0x931FE9A13333E253,0x024DE1A9FB75BDFA,0x72D91776CD72C068,0x2A0EE9C4183F1C54,0x2029D5784F9C0E18,0x9B9BC15FBA769D6F,0xCCA46B070185C479,0xCC96FE8FF985C056,0x7B5E0F939202FAF0,0x1B86A82DB5847F81,0x0B38ADE290C85A22,0xFA121EA953BF81EA,0x3DBE26019D3A4651,0xF1091829F0D7458C,0x72DF35312FD841FA,0x7EA75271DFC603B5,0x7AC326E84E30F3B8,0x96B53ED9700B5238,0x099EBC7E79237511,0xB13D4D100857CB1E,0x80B395819E7F0B06,0x2D145FC6F0B25038,0x04C23827F1D2446B,0x1DBB122A6E80BE0F,0x4222687FFFFBA88D,0xA6DFEF5A2DE786ED,0x11FA59D1FF764FDC,0x576FCFC82BDF3152,0x37700C511FDF5449,0xA2E3B94C413B5079,0x214312737FA482FB,0x756C3C8506BAFADD,0x0C7276E18EC6FB72,0x72BF2F324896D783,0x1260B0A462B2727E,0xC8880693086EE392,0x19C4195A4BD56011,0x88F8F4F0F2CF9058,0x226492C063930CCE,0x77A6B5B9D2BF770B,0xD01E11B0D676B248,0x0929A34B8F13A6DC,0x14DAE2D70BAF4937,0x4B8FBDECEAC38B48,0xE4708E8C84262139,0x752A1756D3C15786,0x88A36F12F7027EB6,0x94544C6173ECB07A,0x5BB36132689120B4,0x3BCCA4E0E23779EF,0x928071995EBE8A7C,0xD7FE9DFB75E66707,0x65CA345FEE2D94A1,0x3ED18550FB0EEE9E,0xE8142FCE67060253,0x5CF20DB476FF0AE1,0xB52C1E665A8E5A30,0xEAA2EBB37424C59B,0x2B0857833428AC7B,0x3D269091048568D7,0x60A2BDC16124EBD6,0x27992A68CE4ABF05,0x48E492AFF3853DBE,0x406917B9CBEBB376,0x00FEE231F7CCEFB6,0x36CCCD8C53E4625D,0xCAED19415C2669D7,0x8759E90F02E49A7E,0xB62B569677D00EEA,0x8AC4E0628DA401BE,0xEA62897280BE0E65,0xCD24A29A1B1A5394,0x39A948C9CC22D80B,0xFA452F4FD7FF2A9A,0x5DFDA360CB03A2E4,0x714AB6088608C3CE,0x54EF3AF9D11B7DDD,0xFC1A316784AA1092,0xC38A94A8E51103CB,0xA478CF749B0B6F7E,0x38916037FE9034D2,0x93183BF5EFD087FC,0xF1F2F44270B90D45,0xFA8465E41CC37BBF,0xB93B649FBB643172,0xFD15CFCB9826B992,0xDEC17126BB72611F,0xCE690DF99C6F7C02,0x3508B821E8C44BD4,0x7C334B6C7824A8AB,0xEF8AE48BCEC01592,0x3734D30C612E3DE6,0x15E2694618D77A39,0xF1D102C1D8A6E6C7,0xB8A1CCF3158E4BB2,0x323D9DC95757826B,0x13AC7606B433F76A,0x2AA9B1423FFDA5A2,0xCF64AD6F798C74C9,0x2869FD02429AB8F1,0x89C511F479958751,0x8F1310165144BF66,0x69D39FBD76A0E761,0x5BD142C8D8BA6851,0x517C694669FF06E8,0x59034F8B879C30D7,0x3192B3EA63A21BA6,0xB682A8BF30E0BA85,0x1E7E849BB46C3D3A,0xD1F5887DD9F08135,0xB67BAECCE3CF521D,0x7C32D328A02C717D,0x700EE3BB65B3981F,0x12F62B913F966EF1,0xF556235AA13DDF41,0x0F01EBDDDB0A66CE,0x2116DE5D5750D930,0x6B1B25E1A46BF0BE,0x12466B9516C6A159,0x1B6A1B415669291F,0x35202E50D47C399C,0xC14A96AC3964BC29,0xED8CE837C426EE6D,0x75D3E8ECA6B1B395,0xB187E84B6049BF0C,0xA16084793F2754FB,0xD79C49BD02466F9E,0x33AA60116DB1BFF1,0x1BBB55753CF4CD9B,0x5BEE564A583C221A,0xAEA04C55159F18B8,0xD22C48F7FC3FA0FF,0x0D96A84ED91C4868,0x30FBF3100F43F3F3,0xDA21B601740A2840,0x609FAA4FFA87A476,0xF459C1624BB2AE00,0x0218AE7CEDCCC060,0xC41326631522E990,0xFA2D13C9A5E93666,0x6CF7A44B61D71CFC,0x0D862E1DA5EB8D95,0x7D6929F9E5C34923,0xEE121E51EE2C04AC,0x173F12ABC363B438,0xABCD825CD126988D,0xE6A0AED134BB4399,0xF405509DA9091421,0xDCAA10B8D910C84E,0xD2A8853ED0D46D90,0x280715CABC9E48DD,0xA0F5799AFDBF3373,0x10D148A830FFE2B4,0x96D896E26CE8EDAE,0xCE2A290BC27146DE,0x929735D2B13013CF,0x677A8098A1F5D24B,0x0517C03F0D51190F,0x7C8363D083AA1AE1,0xBDDF2E735492F26E,0x2B2526BA237017BC,0x52E23A735DA2A34C,0xA797034FA8658512,0x59F478BA59263854,0x9AC7A8A5BEF5ECC2,0x27583003307D7281,0x3BD8E4FB60AA1212,0xFE7EFECA0E854671,0x0FCE78866E4063B7,0x3FC264E0683B0C97,0xFCDC239341AAD0B6,0x53D0B8AEB7246B31,0xB5E03629079EA4F0,0xC876D0028CCB71AE,0xD9F39EAEBC2F2F2D,0xA6E6F3C2FD2991B1,0x122B88024673697C,0x4F1C96F959135F9D,0xCA8B71A9BFB8461F,0x94D26424C61C8AA6,0xEED4415CB9F514BC,0xFE624A50E0F56D00,0xE0268C71CD72DC48,0x891673A2D8AAAD13,0x8AFFCEDC7241C31E,0xEFFA5514BE06E6E8,0x627F4F652D3CABF9,0xBD8D6F26DB9A71B4,0xE5D9EA8A1A491805,0x971FEB8A336D490F,0x507386708884F65A,0x80A27FA20E382556,0x5BE1EA888DBE3816,0x69BE10452CE98E2B,0x17CD77A792DF8DB8,0x64DF5C576E966CA0,0xF9E77E401C6BAB93,0xFD856FD05A99670D,0x3DFF53C9D79DDF18,0xBBA0B945AF021B79,0x907DE188C1FC31D8,0x0D5A53FFAAFEE621,0xF32457D0DF5A4DBE,0x726339BCF7F80AB0,0x79912E8ECEF4AC15,0xE47807D31DE18459,0x6585196221A974CA,0x1EC132DFED947F34,0x751ED51ABAE1C98A,0x8A0EFA5DD459A341,0x439F391D4625D236,0x14D48CFD2763B15D,0x5F16AC5E215AEC02,0xF92A657B9CEB9941,0x567EBE0A770FB9BF,0x86C6E9038678BB0E,0xE7A55AAC397E9847,0x7F7A55B52055352E,0x22BC4145D66B8D5C,0x40811A0BE172D816,0x54A46A189D7CEB59,0x073665AEE424384E,0x087F022FCA17537F,0x3AB13CA1D529568F,0xFED5952CBAAAA552,0xFAF804F936D646A7,0x50F2D459F573A460,0x67FD59A0CA4EFDF3,0xB254A8D3CE3E0657,0x3D9CD978546D6BEE,0x864DAB2CC7B64370,0x20696E8209ED2FF3,0x8B84AF580D23DCF9,0x245CBEFF0C322359,0x1DD56D5FACD6F077,0xBD1C77326DD73DC2,0x545719BBA8482F7B,0x543B5983C6687AD4,0xF9A494CDC1EFA14F,0x0D0664FE946B69D1,0xF916388D07594957,0x3BE03A2E70B1F216,0xF20D9CF8092204B5,0xC48DD2AB37D11820,0x5A40896CBFCFC1CF,0x757024ADF9C6C273,0x84B8ED938704A459,0x6142AEB1691A3C7D,0xD472365B0AE51554,0xFCAFBDE3C3A0C6DD,0xBB6FFB439D29A0E3,0x898835DC81021868,0x6B410BABB44E1179,0x6DD309CFC3A7D061,0x13133A00D43E3D50,0xD50DB674844DFBE0,0x795BC819CC6CC71E,0x02E8CF204A2D1AE0,0x68FDD23AAADC2C0E,0xCC70EA649597B360,0x9AAF3215ABD49801,0x6FB52741BF359DDD,0xA547F362E51B2692,0x696D5995BDAC1C04,0x56EDD22F7DA76842,0xFBD770BB86EC3DE4,0x3231CDFCE5CEDF31,0x90D8D6DFA5D07EC9,0x0EAF3AB0AA8519F3,0xC7080A141F1821D2,0x4BDE27107BA7A90F,0xD82E9DDEF777DD4E,0x27344C9E77DB6984,0x8A253152F62404D0,0xE478791DDC72AFA6,0x43C45351108FD2A0,0xF7EA2D99A4BCC197,0xC24E550CAD3FDCC1,0xB471A5FF42601455,0x4440BFF50A3357ED,0xD14E440F5B1472B8,0xCA1BF64F58852112,0xF2234A16C6F8C11B,0x414CA26E169F8B7B,0x2736D1137918869E,0x3BCBE0D41C32918A,0x188747AE34125165,0x93F9334A894B0BB6,0x965BB95DCF5EB933,0xD429559F6D4907B8,0x163A615E2950F17C,0x21820E5A71121AD0,0x9E6CB0B958C91044,0x4502B7AF4CF71A5B,0x9B4BD7A214BBD5FC,0x2D2FE82607E4978C,0xDB2E0B042EF3526B,0x6C530202247F02C7,0x44548ED601D4C444,0x6FB87DC95C589743,0x1D798737148B01FF,0xD22F6A36EF989295,0x2101979471206BFA,0xB646694A4941FE12,0x9148D55DBDEA962B,0xC5138141606B2B8B,0x6454049E5264A44A,0x721661CDD5179EB3,0x3FE461C964149A60,0x2F253B2FDBB9A7AB,0x359893FCC89995C4,0x8F957D2BFB048E11,0x6F672EFFDF1E3B23,0xC221B8CB177475A8,0x4E6A9FA34E0B7757,0x4D8E848201897EB6,0xD58C30735F76174E,0xF7B1B51739576BF2,0x4F154A77E89558A6,0x4C33572EAEAA869B,0x8AC2AF99E219FDC2,0x3DE1A008154813B9,0x5349D5B76306A0B9,0x72EA4B092BA3EE16,0xB2FFE67F7F2C2BF9,0x7E7A82BAF7CF1039,0x7884DEA59950C89D,0x31C61CE7D554D44A,0x0FEB8A5CC506B701,0x30C79579D07466F2,0x650A82F7FCEDC62E,0x7151D93FBC6BFA95,0x1FC54FD830B66915,0x1D549239A22CFA9C,0xA6A76317B292F6FE,0xB9D6BE14EA5C0E07,0xD2F2922254A2BB8B,0xEF1BE3D519F37DEF,0xF54DB3B5DFF93018,0xA6D3AAA2F30E7D31,0xEF99729C6114020F,0xF61311310BD8625F,0x6E6C071AD5E0F9A6,0x603AC563DDBE6A64,0x7334F37644AFC491,0x1E9274BC91600700,0x13E24BA1237C9574,0x2A8F2E4F7507FA5D,0xD8B48BDD4AD92ECF,0x8278D4CB13150B0C,0x08D82ADB2F052BEE,0x00196BF6854896A9,0x5CCB986B89301320,0x2F65B9B74A5F929A,0xEE5BCCF21D7C37F5,0x33A0A11F4BD9F6A0,0x8B08ADA561CAF933,0x6E80C6D063166F11,0xB6DC8C07CEB7C629,0x1D56F64D09CFACE5,0x496FC17C12CB996C,0x604762EAB556159B,0xFD754047ECECE64C,0x49F519D786CFF736,0xFE2820BA3F338312,0xD8982BA72EB46483,0x192AC92087FCA741,0x4EDD931988396432,0x4EF5B111D0281526,0x0C834C37C3926EC6,0x295A90F6B37E4CC2,0x0D52A606996BE99A,0x1EFA6451E6030C44,0x4BA1A6E700CAFA16,0xDF8929495AAD2C30,0xBC54AB3843470DD2,0x08984E0546AB5B53,0x27EA728974517759,0x2B0C05DB23843916,0xB7318F40407CA59A,0x42ADAC5BB64A4E3A,0x692F8F51CCD104EF,0xC05701B0A39122AC,0xD9A964A5F4EBC509,0x01822C5513C15747,0x2619ECF79B9C6DFF,0xFDD415FCF496FC78,0x318655CC6D1B6618,0x080102502ACCE54D,0x78EB734E9666093F,0xBF03D621ADEFF61C,0x21A347ADF7D98299,0x053474042F2E8404,0x52F10A545AE41BF0,0x25F192A7F6A8D77B,0x5914942D6BC5E4A7,0xDD8C609A8C059637,0x357AD9D8090C2A06,0xA9FBA808BF5319B4,0xF1D3DA759C4A2B1D,0x28C81E51B3F95AAF,0xCB3B13904BE4C612,0xA89FCCA6DA915A9B,0x18CE0AB83934E841,0x3CA1292AE458B079,0xAFDF96C55D2FC475,0xAF54B6F75E3ABF7C,0x0D19AB2A2924137C,0x10FB70346509D2B5,0x6F91BE51DA6AD325,0x56E11FFCAD3A0D2F,0xAF379ACBC512C62A,0x598CDEA3F5AE65DF,0xEF01EBBF925EFCB8,0x26B488761160D200,0xA27C89C90DB693FF,0x8A0EF6B0B81CC0FE,0xA501E6FAB0D1033E,0xCF2D62EC44187983,0x303E3EF0436C833B,0xEB7DF1DCDEA3BD46,0xDD40CC2040BCA677,0xF4C6172E75730014,0x91546C02B80A5A7A,0xAE5756B48A44B35E,0xCB250749CC3086E5,0x408528EEE2B36FCF,0xD4D3F1374EC45A31,0xAB10E476127BCDCF,0xC29D46D939885D86,0x8FEA85958FD3A50F,0x84243A4DA52B010A,0x483FB015F3441818,0xB32337292C6172AF,0xA05729617C8D36B1,0x53192FE148DA64A6,0x4D0213A1737CBB89,0x9CDD59230179C78F,0x20C01C6847702668,0xB32E6CD1DA231A77,0x729644FCDEB99C91,0xDD9516FF5FFC58A7,0x69D2851625209A58,0x10CCB9075F9FBE2E,0xF12280E2078E725A,0x2E96592F90A00A82,0xF0F13448953A9ED5,0x66E67208274D2C26,0xD52A63B44666A5ED,0x0776EA135C5099E4,0x967F60BC364D4244,0xDA035CD2163F59BA,0x3C535E521DA33AA7,0x3FA57C4C045FB11E,0x41B11B813712C5E1,0xA6431B138B9E2173,0x082DE3AEB0042BFF,0xFDB90BDB2B1C8910,0x0E89E46969640647,0x1E7A41CFD3832B09,0x5CC53A9EED42AFA3,0xF4DF63E867D429EB,0x49E911E12928A917,0xF318A09458C77F4A,0x616E3523591D7A53,0xB5F6FE247D2608E8,0x1DC1A155E1A199FE,0xA9BFEA3818EACE07,0x0A513CB4C26C50FB,0xC06754B1D16F0833,0x9D7DED1ADECC0F75,0x7DBCC7B2C8AA9E17,0xF62BFA4D6BD49857,0xE1D86B6C1D552E29,0x5D71954FBB28EAF7,0x3AE73B2FF68A99CC,0xCEAB8D529BD34882,0x75C46FC7351D3616,0x45DC9AC6EBDBD68D,0x390278A347C47779,0xA25A053BC19BCDCA,0xD142EE0CE9285266,0x6EE7BE8320549F5F,0x3FACDFF4BE93142C,0xFF3069349FEA00D7,0xFB938AB092D128EF,0x82F7A3CD106E2444,0xCAAB7C3F63BC6569,0x001A32CFB54F0774,0x6B1877884473B54F,0xABFC486645756114,0xC532F5604CDB1C67,0xCB5F6B108E172085,0x9F5B84F3E15637F7,0x40BFB3CB031B718F,0x80E1105677E05E96,0x9A10CC76E34D36F0,0x95745232E75031EA,0x41065FD4AC97A484,0x32CC576D8D47D5CB,0x33B59EACDC33D8F5,0x060EFC9A63CBDE83,0x519BA60222F5C8CD,0x478CD748B617401B,0x3DF168964274C287,0x739306C29D16724C,0x49C2D6FECF4E58D8,0xB12699FF657D9DEC,0xE7480EC7AA09CB96,0x441F5ABFE316FCC5,0x38113956563374E8,0x7B3F3F6E8FCAA567,0xD690534D12BAA753,0x195C35CA6EC8D344,0x11297F19C07A3823,0xD23FF698278223D4,0x10FCAD8357C1C864,0x94FB53CDA010C392,0x17032FCE1F95E447,0x3B2214DDF818F0B1,0x881FB7E38CB16065,0x6A2097C34DDB86E7,0x34BCD2AD248843DA,0xFCFB78DC26EFDF7D,0x3435F4BB78FEC3B4,0x1813688B900021EF,0x0E7E5C346C433183,0x9F80C0E613EFC096,0xF30D81ED8D994B71,0xE163D7EFDD8E14F4,0xE9D5DA9DF0A3B25E,0xCD952ED15D218429,0x2460246E026D165A,0xF1EE2908F6E9786A,0x0DCBDEEFA8DD9993,0xADB8A1A83EFBCEEA,0xFC657503AF037606,0x06E5B210B894B8DC,0xCD53A700D0084796,0x890CEFCD7DAD3FE8,0x120A38F380692791,0xA01B31BA8A5A1917,0xEB170E7A5F4FFF4B,0x2F3B501C469DD263,0xC1DA8A3CC17AE82D,0x8C5626E88F992C69,0x30AD92FDA188184A,0x117D282F8079B227,0x6671C3412DE56BD1,0x7F95075CA886AE98,0xF4DD542962910B96,0x0927652983D0063F,0x382142D740211882,0xCEEC7BD1FE2CC4AE,0xC5B10028667FADBB,0x949832FF529D59AB,0xBA512F5BA029B69C,0x95F84E96D9489F29,0xA4FADB317E1AEEAE,0xFA839EA0E62F4D58,0x7D115C5A7F9EAAFA,0x952091A494BE8153,0x77584411F011DC01,0xBCA54E069E965916,0x58977295D21C8B63,0xA652BFC75BCD8459,0x087C1989C94FBA92,0x2B92104414303F97,0xA9A3A4A403ED8393,0x000A7C89A3523E24,0x255CEC1596C9A88E,0xCC8C0755226C181E,0xA990214CAF229810,0x2CBD477CFC06E0F5,0x0BFC4151108E7DAA,0x82C29E56DDC9C91E,0xDDC9B1BE82169F5D,0x250087CB633654FE,0x5DBEAB4E4C5F9D19,0xFC24CEF50788BC40,0x38E16A9C93AAD01A,0x554467B767ECD799,0xC78916E43DF55E1F,0x674B22CFAA93BADA,0xF1AB9092481F7DF2,0x0852628DD6A46F49,0xF0C8F343A059006C,0x3F331AA281C60E2B,0x35392A346D1A6BEF,0xF66106F8045AC564,0x0AB1F07D17AC8EF1,0x231703306F2766EC,0xA1474ACDCAEC394D,0x135D1DC17FBF7163,0x7A69222E313740B6,0xEE2061AD303F8D59,0x86D0E3D10DB36BB0,0xE1A092C8B9FE8928,0xAD40253C62944CB6,0x52FD978B46D9FC80,0x0D890A63EA9B9C22,0xB707BF2A6216A5A5,0xA806FA3E5499A2B0,0x82D08F0283EADF30,0x5F04CA9BBE4E89EC,0xA3DE53A125D2C624,0x2A47FFC95A5F7EDD,0xE4CC2235A2FE302C,0x519C7E76367C0EC6,0x732D2D044328A17F,0xA12E2B3D1B44A09C,0xBC58AC06EA77B446,0x9DE704133EC15982,0xE68CD6C558869807,0xF25C47046F9F43E3,0xE5CD6B1C795A0AFA,0x23F1AD8B24A28C0C,0xD66C2A600025C428,0x916FA4F9A569EF0E,0xF2936DD99C4683AF,0x416E63C47BEA4A87,0x96D79F25B227F3B4,0x19676125BCF77E9F,0xB289700D1659A6CD,0x3152F9FD41575041,0x80D30DCA49AFCF48,0xB8C8E0E561D23303,0x5B85134255931681,0xB0EA268D523CA498,0xAF74CB2F8434F347,0x1A1DDD0B3115B34D,0xBFF3B473217BC8E7,0x9D344208CA61A767,0x208D6A8E3F22EC14,0x4430C3F14AB510EE,0x1AD97FD28AED2AD0,0x516C5C78002C8740,0xF3A2A7E4BC91515B,0x55B5BE2C6410965E,0x3B7A3BC00DFCB651,0xAA75B7139E24C9A2,0x9F63C7C594433DDF,0x1E74AB11E79CB9F7,0xC0014FF1F44ADB25,0x242D080EA8144775,0xB238E81C96DA0C5A,0x86F1E1543A87BB95,0x24290C72312E7B79,0x9B34AB051501581D,0xD90319B1E8ED7EE7,0x70CE30FBAC6CDDC2,0xEFAC66A1E0750C20,0xE4ED88B90AA89B75,0x57570FA34BF355EC,0xED62BA4C96786171,0x2EA899D1AEC167E9,0xC442876766FE5CA9,0xB215EF4475A6847C,0x997213446FDDEE15,0xE9FB838FA38CC0B1,0x8D40102CBA721B07,0x662B36203BF2ED20,0xAC04D97E4D4778C3,0x411E1AE630C290AE,0xFC650B1FE565DE61,0xC41D08CB9B7A0615,0xEF7A013510C48D56,0x7DC539E87328E865,0x5299CD4DE85394C2,0xBD45D71D84EEFDF3,0x7CB0E1A44CD7E4CF,0x99EB3D8D8D21CD82,0x914E512E58B63312,0xDE4376774DA2A580,0xE93A7A1159B18006,0xA883400033FFD3D1,0x0AC1187F6B32D1BF,0xD7ADD37FE8460F3E,0x85A6DE2100B01C67,0x15D198D8BCA7D559,0x7A37B21A1EFA0E3C,0xD5ED1FBF99DF44FD,0xBAD7DADE1DD80AA6,0x8DF8787F509756B0,0x605D0EE060A558D8,0x356E14E549DF3D56,0x03990C351EA12FE5,0x30C3244C2B920A40,0x72C779820F3A2358,0x01F9E8336C7DA57C,0x5A175B1DF21AE628,0x3B2289C6D85E90BB,0x6D7C8B3424F605DD,0xE9F86FB0D14CD325,0xA1E4F196D46511C6,0x4C46D0DDD279E81F,0x4C3C895AC3290BBF,0xBC0248F4EEC736FA,0x22F86DEC0052182E,0x85B9EFE208CE0056,0x9ACE5E455B43E771,0x85700C8929F105BD,0xF28BA2E9F999F9CD,0x5DC3A444086CCB36,0xA9DC727A29A8487F,0x61762189A0E75ED8,0x519044D737690DAF,0x60BAF88A87997A7B,0xCA3099C550D51F6B,0x0F656DD36D6F1F15,0xA9766B3D5E917E5D,0x84EF775F94474DDC,0x5E126B4D763445DC,0xF68508E0FE85235E,0x97CDEA60C4D4FE24,0xDCE93CDC0CD26A4E,0x9B7200F455EC918C,0x1BCB592A1AABCA08,0x1FFED868E5EFD1F1,0x79802331C475A5A9,0xEF0DECF2E4A57A86,0xEEF62B3A70A39BB8,0x01230AF657D29015,0x341730DAD4972D4A,0xB1E82F74AD727B04,0xD3587558D5A5BB11,0x6074FC84B9D4ACD9,0xBD78D25EEFDDC193,0xE3D64855ACF58A2C,0x8088119E06E1F92A,0x780022E6D9223289,0x698DB7F7E246D7EB,0x4001AFF6F9C7B706,0x3005AAE000DDEEDF,0x99857D5504704862,0x7FA52C64A898ED9C,0x8D291F93B24A859E,0x40A7EFB1898C2D2C,0xA0B823040E6B3CDF,0x727645C14A0123D9,0x7D79A1387FABB181,0x7E889DB922605974,0xF9B26F033738DDF4,0x13026E50C514E073,0x07C08903800C0749,0x26E363425275A940,0xD1ED2E3B576C218A,0xC73FF0B420B65C7D,0xEF2CA2CEACD0D2FD,0xED59E14D1EB4F4A9,0x637B7D6E344FF79C,0xC016A630DCA79FC9,0x6DB464E81ECC79FA,0x0F32D46C6A02F94D,0x472343DBAB44D111,0xA6DB4F754BB8AB70,0x03893CA47A526835,0x7CA84C9C95D72C8C,0x0280C72FD7DDAD26,0xE853D6B80088C8BC,0xAF5E4D752AA8BA75,0x67B12913407D1074,0xD125067FE2AF5ABE,0xE6B80A67DD1E8037,0x51AE552F2FC521FB,0x35B5ECA96B3C1951,0x83983EEB7E0DD92C,0x4E0A04D4818EB636,0x43B0E0EA7C3C2DD1,0x08C3421F39CBBBCD,0x584B5972EA2292D6,0x8314144D069232E5,0xAE10D07770A2EA5C,0x52E6047BEA9B461E,0xD8C1B3FE7C450F14,0xDC400703799BC56A,0x533AABA20EED7D11,0xC103B9FF1460C3BA,0x8E16480A381A5399,0xC6C3447F7F32580B,0xD8AB7E44F6F9BDDB,0xC726081D8F9A8949,0xE978A7C522D86C54,0x5F6D499156BED6A2,0xF1953B82AB80BB31,0x4BCE8E40CEFC32AF,0x7A79B73AAF68E1F7,0x75C7071B95FA0CA4,0xBBEAA606F3C8E708,0xAE36E02B0B808CD4,0x7EA8BAD14B9080B4,0x2584769375726BB4,0xC80995F29C95CF76,0x4655DB15509C06BF,0x414AB18F4FB049CA,0xE6CF31B48F340098,0x5D336BF41F1A7670,0xA54753FE24600768,0xF9A929D844974274,0x2F0B7811CE6A4537,0x33527CC934C7DC1C,0x511D47ADD7152380,0x4B9E28953A06A501,0x1CEC383C8D6B3CE6,0xF1FEE91090F1402B,0x407A9E7FF11E6566,0x575B5F64027ADF99,0x83180DE296D2F687,0xB82956B462847578,0xDB4ADF7588C0CCB3,0xD496D6E2036E0F83,0xF16D939614E179AE,0x280F0384DA8215A8,0x75984128B98A0351,0x731EF6A04C451A7E,0x05B096A00BBB725A,0x40C6B1C5C35BFE6A,0x6E99790718B604E2,0x345555FCB825F8DC,0x6B9D15363D8E972B,0x730B76C887A08B8E,0x42F10DADD56FBD10,0x15C286E3F8FD441D,0x02704A76CBF604FF,0x3036386FDF6386E2,0x936DC3F0F15F25F0,0xF885BF7BAC764E84,0xCCBD64F4CF852EDF,0xE5C53E214EDAD80F,0x0C69D7F35C000AD1,0x785F4628AB32BD3F,0x5084ECC06842320E,0xF19C3985A25C33EC,0x29306194B5658F2F,0x1B8612D2F8C9663E,0x3807D5DB9DE99E40,0x147E145AF7F333AF,0x87924EEF7473DFC3,0x28ED62DE5D874DAD,0x5BF4935A9DDE2075,0x99AF30D83CBD0278,0xF11B923372F95E19,0x9FC3012BD9CF49DB,0x6DF7EDEAE194A9B6,0xFA008C082F0A5D64,0x80D222AA90003252,0xBC3FDF0F2966C516,0x1A52EE3431F85DF1,0x26D5CB9AB3F80C3B,0x5C235651FDA471D5,0xF082DB382EB0F2CB,0x9B6C2270815884F3,0x76F8593135A5528B,0x6819BA57EC338137,0x1EBE4CA76FDC89F2,0xDA3AA9ABB4D339AE,0xFC4ABAED0D924EA2,0x61430EA2C4708B6D,0x20FA4D519B61CE36,0xEC33CAA50E3600DD,0x4B83D96AEB102F38,0x5C3DFCCE6189A24D,0x13FF3E961FB34868,0x1C00155A8FA03CF9,0x0ADE05A55A3899AF,0x8AB68BFD5C168D01,0x914B3B870DDB2AE0,0x059A725F9E3FDDBF,0x81F8666DF0924588,0x1A1831F7F08A3ACD,0x38C5F5305BDFA65E,0xB3C1F28076063A5B,0x738FBAC161BF1718,0x2DC5B55EFED9D1E2,0x96839493DC1F98B7,0x3BD6B019206233B6,0x935903D73CC3B97B,0x4B452FF10388E437,0x06F6659C88BC99B6,0x78A52F32B671C734,0x74C56C35621F3290,0x70C72241E16D1552,0x6E6A7791EBBDFD72,0x85FCF8550A84E229,0xCA71655A1E27E4C3,0xF313B8958089301F,0xC26521C7FFA8A8EA,0x105E3F7A9FED3F5F,0x1CC36BF7D971DB7F,0x1B7129B0C29969A3,0x202D03788FF29903,0xE684730A1C07ADD9,0xC563E81A3EF9D1C2,0xF8C60C8E84D74DC5,0xF35367DB82DC34B6,0x55279770FA829A1B,0x4FC69146DAAF1471,0xA08892EF92DFEFCB,0x26061F49BFFD0DD4,0xE0096D3BA9185AD9,0x120F0557CAD9FC28,0xF57A1823FAE544A8,0x67F909CED6308A46,0x90F11AE0C5AF0B35,0x9F08B1435364F8B4,0xC259D0DCDC54221B,0x036F097EE953C23E,0xC080D9E23E4AE35E,0xE7763E13A79DF7EC,0xA0888F461A2C6F97,0xB52734C3CF2B4C41,0xCC72BE68FE36EC40,0x781F9E775E3F36FD,0x82433B712DB02FB1,0x3E0B917FF0CA2D3B,0xE7497F033F8982D9,0x4E032FF942CE9D13,0xB1E41942BD2B0713,0xA08F342926747F9A,0x166792D73A31DBFA,0x6C853F5C9B5F3D0B,0x8A1144440DFD4AFB,0x0AB2A871A7B2B2FB,0x7E65453C833EB910,0xCCBE5F4E3C0D63EE,0x8CD627738EE7F93E,0x5A795E70796F695D,0x9B4CC2591E256DAD,0x4C0230002AE4FF06,0x948376A72B1DCADA,0x20BF8EA931DA3CF2,0xE90EFA40BCA45886,0x387E94A1ABC0EC5C,0x6423F2870C09805F,0x56B904CFCCC8CA73,0x925BBD2872B9A728,0xEBC7641A0C91BBEA,0xED153AC4D47F24C7,0x3757CAE4AC3DE0CE,0x1414BBE274F83742,0xA01FD7D1412A2F89,0xC3C57788A9588474,0xC99645DAAEC00087,0x8315BCA1FE6E16E1,0x2ADC2E494ADB0539,0x5B6F020CA3D006EC,0x6C13E59AE8F2FBB2,0x7A9912BB42011619,0xD3C9BF2ECF92DDEE,0x459CFD3BBF92D535,0x6D96725F7EAA0E2D,0xA015CA866A5391B6,0xE2652685894502DD,0xB76F728379CD39D2,0x65878F383095CF06,0x78D50BA386658901,0x9FB0AC3227C18EBE,0xDF1563ECFB7B2335,0xCAFBC2089E7A0DFD,0x8756670F79C8C40E,0xF8931F5580A688B3,0xE7AFECD29F71EDB6,0xDA124AF632478354,0x15A980A4EDBB8C92,0xB468E47B324E824E,0x12E7D291603EDA0C,0x07AA4D8782E38531,0x60C440CCA37E4C21,0x5691E206DC9AB0F8,0xA8FD94DFA5B3B652,0x3E9C5ECD41D98100,0x42EDC8181A232D7C,0xDD974418D462E4A6,0xB63FBAE2644AFB03,0x50EEF36EE6A73437,0x3D2A77245F41D110,0xE7F51A8C2DA351F6,0xB41A9B0FDDAF3A6E,0x60A66653E55E0EB3,0xB090DC484399775B,0x10AA5355DC38030D,0x8F3917E97F2C272A,0xD7999EDD40F8B19A,0xC4C3101A280C5535,0xE5DE814144AF91E2,0x42CB162FF2A4E076,0xD2697C06F96ED8E6,0x8F95A1B19237AE10,0x9295D10FF07EFE48,0x034E5DD16CDA4F5A,0x340AD22788337AFC,0xCA7329BB468067A5,0x5619211C4E4B824B,0x09AB4D454391C80B,0x863C5D7E85EDE1FD,0x125EE4E374DED977,0x17C79E3FDE2CACB2,0xF3EE3652BCFBAC49,0x6F37ADA76C5E58DD,0x7AB023F40FB1094A,0x781E8AC5A0D46538,0xBC4C807EC9B7FDAC,0x1106666C346443CE,0x6A25A9F39C25F554,0x17AB5E98793DFEE0,0x74BD51EC761E2AA4,0xBFB2DF938E6D29F3,0xCF90FFEFDC62166C,0xCAB60F8C9F19E732,0xD9F48EF6FA3E06A3,0x4041002665937006,0x13400FC07D11D1D0,0x28A53CD410B6E3B8,0xEF20DE5733D4F3A7,0x019EE0F6B158B4EA,0xB77F20D422113015,0xCD2BE1E7D16D6371,0xC3857A9CD8BD15C1,0x102BE852DB6BA239,0xE3B110D8F69F9173,0xD378CD6C7264DD73,0xD447BF85437F240E,0x1D817BE4E0A58040,0xAAE31740A75385B6,0xCF8FCCBA8A392C78,0x337B30574ACD45D0,0xF8FA9572DFC8D644,0xCC95083821D57351,0x40F45579B25F5E1D,0xA3F8EBB76DC771BD,0x98DAFA397AB875E8,0x4D574DE883BDDF5D,0xCD484CF11BB9F31E,0x4C2CFD47DEA8F9E3,0xF29FD576CA45F664,0xFE3BE7AB563AB414,0xDC6F66C7F2B566A9,0xB11A1AF256F8A9AA,0x1A3C2E6907573818,0x5E9359220C164063,0x07E5AC9BE6E2CBCC,0xBECA779C75602798,0xCA6C823D3B577361,0x5A5D951CFF9564CA,0xCC98CF12FD4DAFEF,0xBBFE514C186533C4,0x29E7B0A4C1B564A5,0xBAF369E3C8FF2F7F,0xBF8FEF8814A17B30,0xFAE4935BB7B200E4,0x8B19C9DAA22C89D0,0x0414CE9A8263FEFB,0x4F42E0281D9869AC,0xDA52C455179EA64F,0x05AC1F1B99FC872C,0x781EF6841231AA71,0xFBC77F0DAFFD9E95,0xBC5C91C7797E9211,0x89334152CB4BF146,0x4DC501BD8828B377,0x909AE093208F537D,0x09875DD25C163003,0x16141E4E0D3E2808,0x498A4AFBE64CB1BB,0xE925D41987CD04DA,0xA441D7DAF55F22DC,0x5B95FA1F9D69E051,0x345641EE0D6AB056,0xECA5C4EA734A7F95,0x37EAC8C3C9011E75,0x00D1D074EE67F783,0x7999EB5A4E947A33,0x8C95CDA7DAF18ABD,0xA028604EB0B4C47D,0x30D993CBFB301B10,0xBB0C09C2496F5D18,0x435FEA20A9AFA76C,0xBD538A0D240051A6,0x13A9D25BD7A66F0D,0x10B99D8FB2858A66,0x21699D93FF59FBC7,0x2792CFFE0E920DDC,0x633E6A5D2C1C1529,0xE622D98140E942B8,0xCB4FDA236B2BA7E3,0x0A94172016E38D4E,0x33B4F5C762AB70D0,0x96A07480EF558FE6,0xD4024E34D55396BE,0xF2AEE8D5186D0B23,0x44A19B149D795832,0xFFEC1507A6C096A4,0xF8CD071453E2B82E,0x734689257A2FC82F,0xC290BCAAAA9C73F2,0xBE2B63AFD2ABB1D8,0x539E865ADFCCFD84,0xA114FF645178E156,0x261874E4CFB6A127,0xAB9205F45776F8D4,0x4A8FEA97142F446D,0x01B67641D0D0F894,0x76E25962F53AB283,0x7F2BAE77F1A05E03,0xA985FD010B90DFE1,0x18CDDBF206C491A1,0xDF4B97F42D064020,0x6E670D22E297A4F6,0x87C9A8B00FC6BDF5,0x8EEAF757072AF1EE,0xF6C939CCC1347F32,0x494A97AB7478C87A,0xA1995DB9BBD0D0C5,0x82D70EDF448082CD,0x8135CCE1A4A8813D,0x9CC059C69972B870,0xB982203CF57347CC,0x07E98A7F3E3E0318,0xE6CC2FB9398EC293,0xE9A3AF67D08F00B4,0xDE4E70A883E7D5D4,0x038391A1BB34EA31,0x344E10EB27F8DB8B,0x4F9F1D565729CF11,0x3021A05821577B56,0x2B63FE291EA9F58B,0x5DE7E62316F396C5,0xC77716324CB6DC41,0x6EBAABC9144E7A15,0x6C5D43A434181185,0x752363A1BEF608BA,0x803F6EEBE5F56356,0xCE1B666F7252FD5E,0xF7890F9412CC41D2,0x6ADEA70F5F925F78,0x6AF30FCA8FB18A16,0xF63016C13A8176D4,0xA491546171C8BCD8,0x28A68CC52945447A,0x08BB5B83F2892DA8,0xF481A300FF46C633,0xADD60CCD3BE73F30,0x350E273F8CF832A7,0x837DCB322EB15BC7,0x0B7DD327A48C384A,0x60DEE059FF44F3E7,0x9CB61F3885578255,0xB4EDBFA8499E8A34,0x13561D5756D8FA84,0xCC970B0E9B6F9370,0xCCDE8F4D3312C03F,0x892B724FCC911E8D,0xA3AE0CACF67AE8A8,0x25DF5FFA727150C7,0x9C170FEA65D8E96D,0x7ABC8A946ADD5A1A,0xE5B50584B8DDE155,0xA68C7428CF987EC7,0xBE01397330889B41,0x0E2CA40BA8A9488D,0x4716C56BAFE049B0,0x6FC54D20835B875F,0xF0E7178D20D861CD,0x0FC5B0F38CEC4088,0xFA67BBF19E9A4A40,0x72C8773CED85DDD2,0xB93B171D4D3025DE,0xDEB3DFA025CCF9E9,0x502335062F7BC673,0x407B1344FDDB00D0,0x190B5ECE218DFC7E,0xAAE3F9CECF7A0102,0xB8E6FB4FC71BBE6D,0x65D787F9372B8B71,0x2EE8A3F16BFD65A6,0xA2505375661095CF,0x1BCE7E2444062A7C,0xE6EA0F2780E843FF,0x727723D2FF55AB5D,0x8A3C69F3AA3EF98A,0x6339D5D912F18932,0x01150B07C06C9E48,0xD89CA19CCC51DAD0,0x5FA683B59BB1B5A2,0x314608F7B197BB94,0x836BC1D3D1973928,0x519EBFC455E7240C,0x3E750407E14B17CF,0x76CBF92F229C28CA,0xC8694979FB80C52D,0x5B0D8688158027BE,0x2723B9E043AE8090,0x746651DFCEF3A282,0x69A2C36F5A365974,0x3CBEAD072366DDF2,0x2CBFAFA79650D400,0x640EF0B4AB62C37E,0x202231183BED0665,0x9321C8C85B14FCBC,0x03A917D292520521,0xCC07174AB9FC5B37,0xEAD8629FF62D0F7B,0xC6949570B47477A9,0x40823AB09F9EF4C8,0x14B9074BEA677D97,0x79D91F1B89A47415,0xF954207DF2118186,0x2E1B4601BFF7B1CD,0xE2E0C042CE2779DB,0x0D6C7E8EF71D1F00,0xAE5B92811E12E202,0x91A2974A3F4FCF15,0xE9E9C410A1DCB0A7,0x2C6F3E410CC1A5E1,0x262858EB4583C9E4,0x3A13857FA9533E92,0x6C9A924CE2519657,0xD23529870A7DE8B9,0x16ECCEFB48F1A17D,0xDA16E2D284C03190,0xAB3B864625FA4EFE,0x17DE36202D28584E,0x5CCDEE6FE94BBBC0,0x1F0B1F619900093E,0xA80230C4287E2F05,0xCA7D8E1A9F10AFF5,0x7D1DF6BA2E9F4F61,0x9BFE51EE2CA05A4B,0xA7FAF560D0E810D0,0x020474DE98C2C4C2,0x265031609656C4F8,0x3C49CDB4C319049E,0xC9B42676ECA1D685,0xFE4E548560B70BEB,0x3BDBB64F9FFD9E30,0xC14747323AAFC295,0xF0303E48B3A67482,0x27B82AF6B27074AD,0x9BB4A2FE3FCFE100,0x462A84A45FAE330C,0x0A86C3CFB417A1D7,0x70A72C63E1FC5392,0x4A2C785BC254101C,0x28EC6B7DA908DD0B,0x30354711D2B068BD,0xCE17A12898552ED0,0x4DFE3F474C0FA3C9,0x1D95B839C39CE5EB,0x76D6BD9EF3C3993B,0xD56D150ABC18DB67,0x29F165042650FB22,0x576087B4773C46A3,0x65056FD7F7CB48D6,0x6ACFB7D0B0CCFF94,0x16E7972226A43455,0x6FEE7A61B0A39B05,0x07A103F6FDBE5636,0xB8E586EED3B157C8,0xFE6D972DAF9BAA0E,0xC517082FBC44F34E,0xD2BD14F094B3FC49,0xE1CF622E1F918BBE,0x28FCEFA9F8C3EECF,0x385557DCB0DD5834,0xF719C7649DC084AA,0xE2678C8CD2877D6C,0x3670D39CFE59B644,0x4CD38C48040EEA3F,0x037AC0DF190D2499,0xA45DDB3F14D01462,0x8009A6EAAF38C8E6,0x8AE73C6804480DA2,0x5AA0E1BD759D656C,0x1997D90A2659E438,0xB687DCD5542B55B9,0x4F1B6CEB49AED552,0x1138115DE88AB02A,0x788C168DBB292562,0x1AA54A343B4D9E90,0x4183D475C3252F24,0xD9D8BFFFF6AA6CDB,0x16B9732E07BF6086,0x00262EBD87B8C5F7,0x5988358AE3601CA6,0x6D3671C053857377,0x202ED4CF608FEA38,0xD26207404E53223C,0x5D6E2E15DAAA8F42,0xEFA2FC143FC9C0D2,0x52C03E2D102CEE22,0x5BE91952524305E7,0x6B772DF6CCABEDF1,0xCA57143F79FACD23,0xE15FCF301BABB133,0x9C9D9068052F61FB,0x9A991357F5DE0781,0x45FF99A186C7666D,0xCEC39DB2521F7E24,0x9532483981B06423,0xE9EE916990064030,0x5E7F51DCAF219D01,0x4A09C587BB077C95,0x679DB6EDC1C1024B,0x9FDDA8FDC6D41F44,0x57C7F155C21E399A,0x12D59788C49D4AF8,0x8F23A9FC5B621166,0x779177FD51F08837,0x4B33FEEF2F27E00D,0xDC17360EBD2DE291,0xD50A0EC18D25F4E6,0x988289A1A9804721,0x69D6A0FB48D16F93,0x83ABFF9174291E4B,0xC8F8006B8E1FE17F,0x22531A15F0EE1174,0x6D74099CA0FCFB9A,0xBE84896AAD6DCE64,0xB880B307E6340C4E,0x8D6BE0C458CA61A3,0xF17FD92ECDB9652A,0x410CF3A68F4547BC,0x6F6BE40531D7F7D8,0x39C53AA1FB2C56E0,0xFB7CFACAA8F61F9D,0x60E8448A98156A3D,0xF11E103393D2FAFF,0x54D1E323AB0A5E12,0x359368E215A4A967,0xB094520F3E8B6016,0x2483D66FCBC1B05E,0xBA0FF3A995E79B4C,0xF8C95A4FAA626341,0xB4457CCBCB2310BF,0xF3A1675ED2C18CAE,0x29F7F566E233A938,0xD12BCAF893421E0F,0x3568155299CF1244,0x1827055AB7A6E4BC,0x8D8F9257752AC5E0,0xCB935E26FEFE1DEB,0x503271CC107E9C14,0xFE2F2DFD210E9694,0xB1CF1A8E92D5482B,0xBA8344FF4B53B991,0x29422E760B3E22C4,0x1378B833115ED2C9,0xD1981CD07A7C0411,0x6F57E8D054D54326,0x9A222616105EF096,0xDBF90490C16ED088,0x6E4790A56F2785C3,0xAB3080DF04DD6556,0xFC68CD9E79EE7BCF,0xC26554FBF43B2544,0xC60C349495BB6D5A,0x4177AB0B32D00434,0x84501748253F9502,0x6C3D883EC972A1D8,0x3526BEE2CD346C35,0x0E47BBC55957C2C6,0x2BDF38DC78B1A355,0x43D6AD573A00D2C0,0x1C9F25A130FD6626,0x6EAA4E153009A30A,0xFE7BEC3EEF64107F,0x3565EE63B9A37511,0xE4B4DEF14E149658,0x1F3C42D681208D77,0x7747709D5061AD92,0xF762F241DF7A5280,0x2268BE9EF61E2321,0xB897BAD15E387F8D,0x221781865B2BBB9D,0xB24247083FF1331C,0xDA2A6666ECEA9566,0x808E03BF306E4525,0x63A27A32413B954D,0xC9DD561E2CDE6341,0x4A84B297AF9A5092,0x0A90257D44A42FC3,0x42E24D00811F7B70,0x15DD82908746EBF7,0xC817ABF1610D1648,0xC91B6CA7E591894B,0x057746BCD04F7211,0x30336DAE22EEC3DC,0x76E2BC8E6E1AD9C3,0xBD47E12C0B5086C6,0x9D9D2F00320019E6,0xB04171BB98C444BE,0xAE2BA54E1C4276EB,0xD7966B3B3AFD569B,0xE50A42B41AA351C7,0x79A96B174644922D,0xF670666714C0EF5F,0x413F7C763E97ED29,0x507F3CFD6B69F49A,0x69F31B7A57448CF0,0x89E94F5D5FC3923E,0x079705331CB7B289,0xDD218BFBCE59112A,0x480E6E4BD2501E2E,0x98F7C2A84E891356,0x40E6D71BB11ED5B2,0xC3C1FA22D3326D3F,0xC7F56FEFF76F2CE5,0xB449B91A8F75EA63,0xDC2F8B3C98B8F90D,0x3C552A8A5F4B8A31,0x0C9DA7BBB24F2A96,0xF70BBC322BC4A5E5,0x3EF70BDE047E8CDC,0x08E8DB28AB987CA2,0x9FD54AB9670A264D,0xA9AB2BF6DCB47B9C,0x6287175C7BC6F83D,0xE9DAD17A20FBFADD,0x2C8D849564175376,0xBDE3500F9234AD06,0xF2B18CD32B697117,0x0047465076616BC2,0x15AF04E58757E74B,0x695DBA197F9E8666,0xF1CE4D8F1728E445,0x38F6EF341B51F71B,0xED0DDC37F5EB90CA,0x031C9ED6EA55A3E4,0x0EB0C9AE611F54B3,0x68E7DC0E4B41CAFF,0x01BC0216F76352D3,0x3166591C83ED8786,0xFE7A39B763E87AC1,0xEF49A819EB3BCDF8,0x8B02231663BA52E6,0x693745BA14D649C4,0xFF6762B4B039D9FB,0xAB45C5B1B9C9125C,0x8211D6DB7CC703CD,0xCA646F32E835CB98,0x652C3A06E1652688,0xC49F8908C0FB1F3C,0xAB8B19BCDA0B5B8C,0x7FCE3D26ADB67D79,0x2BF6FCF1D9D5DAB4,0x5FCB4889C45EE314,0x54086C54E2FBDF5C,0x817B3E9DE602C73A,0x992579BC4EBF152B,0xFE87BD8A31777768,0x5910B209591FC467,0xA3FFAF9D50A68C12,0xF34E96A71AC26766,0x66F9A0ED34278FA8,0x34BE26BA876152E2,0xEA492E8C2E96EA36,0x6E1771809EE40537,0x34866214E0DF7324,0xA59B3DDB04074EDA,0xCE77E7F5EA21648F,0xA384D92DB9490F05,0x10EE9D3CF7912E4C,0xD4A90B94696965D8,0xFCFA455A0FD9B6D8,0x04FDB234A8E0A96D,0xC69039BD16AB8575,0x5C00A05219CD6B1E,0x3C5F025B70E799C2,0x82F51778DD10CABE,0xBE8D44C237C0BDAC,0xE622EEB6776EB2C4,0x5F50B9C374AE0840,0xD443EDB4834A4727,0x39F5C6147346B745,0x8DE3D1606A119F3C,0x64C56ABAC7B2802C,0x239E9AF77DE7DED3,0x474BAA4DA26CF443,0xD7FA70F3531604ED,0x169D1D8DF7864C4A,0xEF7E0B02197758D5,0x62F1FB6B30CDF3CD,0x9940978CFF8CE992,0xF4CDBC617DF5F796,0xE795F26D16B40839,0xDE40757C05B082E6,0x218C47C5708F4337,0x7D479428BDE4F17E,0x3446C309805A2D63,0xEECD5097DFC93D6C,0x44FA497AF30CCF3E,0x8D51F454DCAD33D6,0xF08EA814BC9CA2D1,0x46A4FE67EC9312BF,0x7208DACF84BC3E13,0x1883D05F7ECFA351,0xC74AA761E4804CD7,0x192430A3017FF4AA,0x95ABE12518AA618C,0x823719F8C53B939A,0x3F36F1FDB414BD21,0x2655CC1210C1009C,0x969DCCBB4CFF3103,0xCFB05E3AC73FA698,0xB3AE612424AFBA29,0xF654AF377DD53649,0xF1CB529BBE9F0939,0x485238004442CD81,0x73CD4F7D28366164,0x085286709AE2FA2E,0x6FA95D7E001FF47F,0xA6D2F83202D0A450,0x40B91F1F7B04344D,0x0F10B9CC6C2D44F0,0x95382A38AF0D8418,0x6BDBB1482887C0AD,0xD08B52031731C05D,0x1785C8EB6514CAF7,0xCB9CE8BF9469B0CA,0x8EBA7AEEBB9871D2,0x602B7006DF7E4AC8,0x9B74C84561DE4366,0x5B6AA2080F16730D,0x6FA9264783D981D4,0x9F9F6ABAB948F121,0xC70F4969F148F947,0x1736725E7CE1236D,0xF52C577B6755CEED,0x542DA5C452FF521C,0x69CD048A451B12A3,0x94DF5FC550DA6367,0x66EC3ACAE2AD868B,0xBD31D52169A52013,0x84AC8789E414EED3,0xC404C33E8531F17F,0x9A8E401F04DFB382,0xB129A9EFD7244DB8,0xD6B1FAD8C12F7577,0xA1996AA23DF2F289,0x1E0B46DEC7E3DBFF,0x2C2FD0705C5E10D4,0xBC0815A7C1B25D81,0x7206D4EA8654C1E2,0x0F3FD965E74C406F,0x4425C5B01837B428,0x7AD656083453DED4,0x4516423FD57DB68F,0x8A4E2887D1FF2D73,0x1CC54F80ACB87D3A,0x9978CA1252F3B97C,0x275FA18DF9A67F9A,0x5422B472EB1FB293,0xC18FD344E7D4A5C8,0xFD2E8B8D2A77E32D,0x7445D5FE017F349E,0x3E468D8F29B3757E,0x47D71F9B19A3390F,0xC2E9E9F3A23304FD,0x80E5CBBC2C9E2562,0xD1A2569BB2873461,0x49CD319AAE3AC2BB,0xFDB13166964B45C7,0xA669A9E6BA87DD3D,0x1D95F0F95F1F3228,0x0A1467DD9C608358,0x32744340C1CAA547,0x508651CE98FE1BB9,0x8685AC909EDCC22B,0x1D539C941018B4EA,0x38C705AFAE797DAB,0x8513C3F0903325B8,0x5E0BA7E573FE3511,0x6A16DA3D7699C246,0xE8A1CFE8BF09C365,0x37AC5C448560B8BF,0x83B7A079457C3A78,0x5A338475FE95E198,0x02352EC8F3D68D61,0xABA83E965251208C,0x7689040B39B2BE3A,0xF7C06C4209DE5955,0xF143BD818EEA455D,0x74625C18625E05F0,0xE445686A3CCCD0CD,0x212945FBF5694FCD,0xB7E83CB13358B2D5,0x1CF375705AADCC2B,0x9E1E3EDC7038086F,0x6C9B5C6EF2CD47AD,0x4E4C7F85AD71EB8C,0xC99FFBC51ED02F8A,0x6E421347FDDAFD07,0xFED66BB7C1F104AC,0xF93F4EBD68A8EA75,0xE0E6DB78B154996E,0x78F135AA5DC5CA9D,0x22A34316E887A15E,0x9231B4C69FBF2C07,0x80BF346DF199F386,0xBA3125E10A7C6543,0xFB51C273BBCFD54A,0xC71574E034434720,0x404D5125B3B00145,0xA58CF6FF593B57B5,0xCD5A855226255FF9,0x92819A81F9771AC3,0x007093AC1465CBFD,0xB8DC87F4B1F4A8C7,0x25DBE33C1F51D6E4,0x773AE6DC5E1DECE3,0x77D785D9DC300877,0x4F2619EBD85CDD98,0x559631A873613A98,0x53C4D47B6230EE08,0x967172F198928878,0x2D056334CE63F5D1,0x73285A1133F7F811,0xD51EEBFCD2B33DB7,0xECCD49C80E3962FB,0xDDD9F38EE1820CB5,0x7D3CAE9CBFAB137E,0xE7C9FBD92BF0FAEE,0xB902270FACFD40CC,0x224B83431692D22D,0xCAA912E7D54EFB36,0xE90B35FA7F50F6DA,0xD47C98AEC7290DED,0x3290F2675B1C4FFF,0x1C6A8B30B9C08D2B,0x2EE9125F5401E4F6,0x64EC5B33408E552E,0xD88123D5CBD7658A,0x2AF7A773B13938BD,0x99CF4DB87ED10D3E,0x6536F872BA2081FA,0x61106FA0E83DB970,0x6EBC9B36E69BD05E,0xA46A4DD94271C7A6,0x8422DAAFA106D2A2,0x858C0FEB82D77107,0x0EE9E282D85EDDF3,0x7851B214743D743F,0x21112E4165615942,0x58DC3E93BDB3A103,0xF198B460736CFED1,0x206692A4B69E0A52,0x5431831B49E8BE2A,0x5AF597423DBDA9EF,0xF58765E1C69D355A,0x39896EDEFDAAE940,0xBDC7DF92C080E18B,0x4200390EF442FC46,0x254932F4327C6500,0x7FEF30A1BF355E7A,0xD8007448EB8A6A2D,0x8990D34981F1DD6C,0x7E6ABC7CCB0DEC0D,0x77A2DCC904D45C07,0xA9AFBF3C07119A1D,0xA5D4EB96EBC5D38A,0x1B2DA641138C6D98,0xE22EA6EC4B58A71A,0xD128073C4BEB6BE3,0x30D9C5970C6843CF,0x2B1A3BB73E828645,0x21948F583D7309B0,0x63C2CCC9306E25A4,0x7FE694502101F950,0x75F62403028AD5CD,0x98D320482B057929,0xA0DC23DD7DB7F5A3,0xAF6279CCD887675D,0x326EC8C5476F61AD,0x3BA0D4F93081F79A,0x56D7669C440FCB22,0x10955BAE8ECEB1BF,0xFA233516D9E05007,0x453FB124178F8B03,0x71AEE676FCBE26CF,0xE8E3DF653F915307,0xF280059DAE13D5A1,0x1F340A623E54A79A,0xDA131E94A8698A73,0x9608AE23786440A8,0x932055E58BF2B468,0x040779A32A8927DA,0x36E3BA39AC8DF6DA,0x5CFF3330F4A5BE9F,0xD3A4692128C0A5BC,0x1C078AF15EE1D205,0x5FB6A396986C1FA3,0x99BA0F53EC1CF4A9,0xC2504CCBE9E9ABE7,0xC0C3781161D6BDC9,0x5BFDBBE081EED8C1,0x263646B4C7FAA07F,0x8BF1887B0D89FE23,0xC102CBF6083E5AE5,0x118FD0C44E3A5626,0xA879ED48AE292923,0x2C8B5220AEFDD787,0x8B66B57667F1EE06,0xE1A6F2E6A427D0B6,0x13601EC2B2A2D1F9,0x84241F5E839D2F7D,0x10BBC54D52EFC049,0x1C0C5339A776A6D6,0xD8AAECDAEF0CEA2A,0x62D2DCBD807D20DA,0xCCB403AAE029937A,0xABC02F4BFC0F4CD3,0x4345BCE44868D132,0x613612D63DD6214A,0x8DE40D5B04E9563D,0xF96F81F5ED2F7144,0xC49A15F02A6ED20F,0x43F3A324CEE0ECE7,0x534B2B188791BC82,0x8C29F2AA97B70D02,0x6FF831CD0D00CD0B,0x4AC277CBB04F867C,0x1CA19BD2CCCACF18,0x2011CE805322D2B1,0x47ABBAAF9E0F7B4B,0x59C912B6EFF117FC,0xED1810B3BE0E2B0A,0xF0E1E8338AE803C5,0x35F0478CD1E08A2F,0x1A8266AF07F50E7C,0xC20F808239C84BE4,0x34F29B39B8F80A5D,0x911C987B73F96279,0x51831D4A35FF5BBE,0xEA40FDC966953F34,0xC33233C65A7E7838,0x15FF14932BFF2E07,0x8F7F14661469FB5A,0x25D39307553A4AE2,0x394A8F9F492E400D,0xD1A60B5A70CCA488,0x891257412DC2149C,0x3239A74253282BE4,0xB0C3356EF7E6CD03,0x6F071C1C95818E1D,0xCCAB3F3246DF37DF,0xD201F6306BF22F2F,0xE27022C11BAEE6F2,0x7D3DA3803F375617,0x82080B621BCC6965,0x04E03741D0DA3BA3,0xC37C108556293333,0x3A9D91EAB674B98B,0x7811B374390783E0,0x47340B97CE0FFED2,0x749E5B41722CF191,0xCF19882483630C96,0xCD81CD5CE900E138,0x991D80185AB6F185,0x07C2F446492DD4A2,0x490E00062EC76CE2,0xFA59211E9C0E9392,0x3C981EAACACDD805,0xFB80BB5FBDE3CD29,0xB88BCB51237742D7,0xD83CD88877DA25C0,0x1A2F39D18E61323A,0x25196B15BC32E9B4,0x7C7B93A31605EFB2,0x01396B10BB44FFFA,0x0E2EF48B88456126,0xC63D4F037A034EA3,0x0FB15362738B8E95,0x550AF0D6B8334BEF,0xE1445521C268AC87,0x7D3FE4344BE04F31,0x9E23DB1DFF51A16B,0x950447FFEDFAECF2,0xB87A9612E88FE5FA,0x007C4859A8FDB311,0x1323112A8AA4F9DF,0xCE8092D19D3D371C,0xA963DAE2A439A31C,0xF6E8C5484CD0CB2B,0x4B1F2087E6FE019E,0x97C7CDE7FFE3208A,0x77BA87C4CBF02379,0xFB3DE8CDBFDF7EA9,0x1415BD08C362729D,0x7B4709E70FA16FD3,0x6867536AC77842F3,0xC5468C7847271CCD,0x05B95F5E78D7C8AF,0x0617D4CBB9A00E45,0xCCC87915D43A92AA,0x9AD58E5BEF0815B8,0x74C94324B3F05B5B,0x4F5BAE79045EFD1E,0xFF8373CF5732DEC2,0x32ACA62B741DCDDA,0x35E67A1ABF4F8C7A,0x0E4C8B9F91344129,0x8E1589D0104D0FC3,0x067B417387DB7184,0xB1E56406EE46F505,0x7471FD7ACCFDF21C,0x192679911F879121,0x2A8BD2BDB635019D,0x637E976B7FE94112,0x74E3BF274F67B08E,0x1C3F1EDDE32A43C1,0x8A90260C1CD85A92,0xF0C127762E09A9F8,0x07C321B453633087,0x0CB0088775B957EA,0x0A74B387A4125730,0x33DF8F68E13C27E6,0x51686C2FD56615A6,0x46270B35D8904CF9,0x3311F123051F4785,0xD98A98B96CB5ED43,0x384FC86B94E028D1,0xC3A92F4D42A7173F,0x0BDF5208976855A7,0xD035A3CA4841582A,0xF8426C51FDD23DCB,0x8E936E0A2E0A3CFC,0xCBACB9B75ABB387C,0xC32FB0899ABA8A7B,0x36894D3A81087889,0x44777143974987B5,0x9F6C4FB59DAEF779,0x887C0983102834C7,0xB2EB206B278B4121,0xD178797AAC9562FD,0xE94010CE7ED6964A,0x64E0EBBA1329DC9B,0x13325A826F7578DA,0xC90137BFAB25661B,0xC9C835FDE2FD03BF,0xF1149BC0F6BE49C0,0xE0D366A64604BAD0,0x48BCDC91F31ED35C,0x4819A44673BB7266,0xCA60300EE1CA2A51,0xB5981D91B2B6C40E,0xF1495D83668B22A2,0xD5CEC10847D2BFF6,0x0CEF8627A508B3A1,0xA6DFA4ED386BFE0B,0x75E2EEBA062E3F90,0x70E33BCFFBD244BB,0x4E7EF8B60C50EF43,0xC7EE4F81F2E23D57,0x52CD93C060C54679,0x617CC900D64D7627,0x31CA74CAA8D35423,0x8E4FCC5606F4B525,0x2273FDDE5EA46AE3,0x11872D3DBB26DF60,0x98FA64C659512BC5,0x9A2617A7AA1CD31A,0x687CA3C2CC422FD9,0x2D4B5235674DF77E,0xA977140408836853,0xCE14869A36A03D0F,0x768453299C2965F1,0x2E90E1B23FA9E047,0xB4BBA7A8C7946A78,0xE6488E4D76F38298,0x551840D47200FD5D,0xBCD4A49AB8368981,0x49147EA1D236473D,0x1A9CDCFE19D5E1A6,0x4BB79A707AB9A29E,0x38031969E19C76BC,0x93108AF55944D25F,0xF961D79C761EE155,0x939C0CD30DD53C87,0xA09932006F9028EA,0x505EFCDBA6EB47D5,0xA2395FDEFE4671BF,0xD33F80B59B9D928A,0x96A452E7F41180E1,0x16EFC0794679AF83,0x886C52AAD884F715,0x4A3AF1B76B4FF3D0,0x90891AC6A3945703,0x21D8C5FEBE9F7A24,0x257B8532FC8FB788,0xB1B406FD9B135256,0x1BABD426B742A8AA,0x5CD4B4C5E267B47C,0x7BB4FDD80720FC08,0xECE62DD447B24C6C,0x9E8591A7CBEB8126,0x134425E1845FD2B2,0xDDD1F8538BAF059B,0x9C9A2143E6B5EB24,0x7430B6093B2E7EEA,0x38B4A469550DC4DE,0x49E3042F94984CF9,0x62143C8695CEC25B,0x8190FB1C47DB9C76,0xEC71A4D13C504510,0x7F75C5755E783F1A,0xAEAB6AEF87C139A6,0x35B7197EBBECE711,0x29FE370F408F4C97,0x071AA36A46047AC0,0x89233B6AE0126CA2,0xCC1581450E4B9425,0xC8999089F2AE8BAF,0xC4D305AF47DCA96C,0xACB4DAAF5870A6AC,0x663CFF2898EE55D9,0x10C95A22171CE546,0x2D89E8383AAA701C,0x138C2ADF56ED6894,0x13DC49FFE1AF8B4D,0x25A5881AF35A65B1,0x3F7B72A7D874CD33,0xE06E738E65645261,0xCE904DC70F9D9EF1,0xB64DDC65D6C614C3,0xAE302C6DFF33CC32,0x6309815856CB3CC4,0xE1EFC2CDD3FA3DC7,0x936AA03B449BE07F,0x6FD59C7C251F2F85,0xAA2B403B28F65159,0xAB6E820EACFBE125,0xA26134A77A84F90C,0x2A50764F8901A7C3,0xF07A6511DE7D6A7B,0xFE892BD586606FF2,0xF85109CED318B3AD,0xA602F6A540A8183A,0xAB329F456D84C198,0xF7ABF8BFDEC5F572,0x0527EC6100FB2587,0xFD4978AE1233601F,0x184144D730D3405C,0x1F6F903E37029664,0x767BC6E5F8AA44E4,0xC43AE231D18455D5,0x3A1EFFB1C1A7C942,0xFF6E1D4DE120DF78,0x786480ACD9356881,0xC54AD70FB613D56E,0xAE44D2EEDAD7A290,0x8C4E1D3F93CB9445,0x3A069D344541201E,0x8AEF628464D8FA1D,0xFE981BF49BFB4367,0xCD9A832A353802F1,0x10C27642DFE759BE,0x58D7B6B6A5465338,0x8D2B7D101AD1E8E4,0x9C97A9E216C10B76,0x1520937E4DBFA49A,0x999C786ECA0DC92E,0xD69AFD158CA620AC,0x5C9BAA320FE0CC88,0xBBE98CC626003C0E,0x3296ADDD734A5FD3,0x56A8844F4873E871,0x3FFAED5A50D94C7B,0xEAA5FEA0DCEA7EDC,0xEBBAF440BC458E7B,0xFBA3274809264D5F,0xF8AB3744D653E9D7,0xEEB8D5A21C80851F,0xDD77E5B45873A294,0xC41A47AA5D90C585,0xC20FD76D082408EA,0xFB281144C71838CF,0x56E56E4C073C8F82,0x43F01A1838458BFC,0x890546EA452F42F2,0xF894072DAEBE4D83,0x68E1560B6A689BD8,0x293EBDA834BEDDF3,0xDFF5D461EC0C9434,0xA672139939C76E0E,0x3A3670018BC11528,0xB723A69991281E55,0xCA5688F0AF248664,0xDB4DFF7E10487A20,0xED311B8884D4BC8F,0xC3293D3DC9F88463,0x312705A5133E60C4,0xA35F0E093202486F,0xDDD6D1CAE78C9A20,0xDEE8DAFD6304D408,0x1EB993E710695339,0x6ED7D03ABA787FE5,0x07794902167A745A,0xA4453B1C3A62CC70,0x29D98AE6D1CEE9CA,0xFF25F0289CF38389,0x80DFB36E70105266,0x7ED68323AAA52E16,0xBFC21AD54069A625,0xC99DD983D50AD691,0xE3C3854477048F44,0x92ADBC5F848998AA,0x71DB68057430513A,0x5D9AE4499694969B,0xD4A97E33AA5BB786,0x59E22251479152E6,0x27F161F60ECFDE5C,0xCEEFBD1333A636A1,0xADE864D29FFEA8A2,0x1680F1845C809659,0xBFAF3AB1DB324866,0x05087A83F90FB568,0x0F45D087346DD8BF,0x086E9EE5C28AC8C1,0x4C726DC02EE1A141,0x8D3FF164DB1E7DAD,0x3A3FEF23C10A343E,0x7079B72D9C3FD6D6,0x3CAC7C9892AF0B55,0x29B7E3ECA0E12B43,0x34DE64FB2B19A302,0xDCB05A6FA2EF7F28,0x7E9B6EF2BEF17B00,0x3EB5C5F3D889C664,0x80FD2ECE757C6ECD,0x896DEE61F38688E8,0xD9486BC037F5CC54,0xD66F6D77CD90205E,0xF117F53435F475B6,0xB830E36E08477DFA,0x796EB9E0BD91CFFC,0x5C7D759410BBD1FB,0x04F27EF0CA375E33,0xDC16004B1705137B,0x1AFAE2CBD7F42DB4,0x6E7DF5E87ACAE5E7,0xBFD05480574AE87B,0xB9ADAA43629D7013,0x05A878922A2A59B4,0xB3C2462A3F243942,0x3CBBB9A53AFA90EC,0x780E5B6E0246B203,0x8F693D96DE74D878,0x2373FC9F24C596FD,0x84DA51733B6CC588,0xABC97B9E6C3BA658,0x5236793CF71A7BEE,0xBB027B9B246C7954,0x6810F577F6CC5B8B,0x9E35C6AA39983015,0xFCACD001E89BEBAA,0xF9F61B453C219613,0xBC0332ACCE2A8A20,0x5D3C3FBC52C96E7B,0xAFA6A7145DF37EEA,0x948B5AD8B040880F,0xF4D31FA62083965D,0x3414F26A23FE62CE,0x44BEC0DB1623DC6E,0x8211C562EB1A3411,0xF5B7BF56F3A6073D,0x8A6C6026F5F3F1DD,0x9420495AC12AABD6,0x4114372078C82C75,0xF350C3AC0127385B,0xE0950B41C2702A10,0x971F889BF8A2A0A4,0xC2856B2486F58001,0xD012C49E326AF9F5,0x57D1C990A3B45812,0x4B9B96BB9E16F5F7,0xE91C57E7898D9C19,0x891D95B32BF0750D,0x474EFA386C42B482,0x25C87A8CD8146035,0x292B81A3A786013E,0x6446236AF37547B7,0x14FC6D5AFD8D4C7B,0xE9AB5E3C8ADC7E9F,0x5AF4E0FD9B9C769B,0x93722B78B46EBDF7,0x3A7AE5131DE3C2B2,0x5299FF3EA4C950AA,0xAC68EE28426E4A4A,0x7C7EC627B033750C,0x2BAF01E6C76D1CB5,0xCB8E1EE7EF270D24,0x3929F7D2769F7AD3,0x265D2FCA6B77F229,0x47BA7FD68654DD6B,0xAF5E9B6D08C5A006,0x5960570CBF435B4A,0xC167A5446A0F29A3,0x0A2EB1BDFE95C246,0x12407B0EDE974DEC,0x8735B4D49B930563,0x7DE376A24ADDE26E,0xB04F4B20DB135AFC,0x529B4AB05E66A958,0xB716188133FD3A6C,0x0027A2DB5BD14CEA,0xB4220412FB17E4DC,0xE7B0A6FF350489A7,0x894C97244180A7E7,0xE83564567A5B0183,0x9DFA129DA90F9034,0xA953EF7E7C04992B,0x34743C509E9D3B01,0x0FAFAB9BFCFAC3E8,0x5EAF2F42A11D00E2,0x80DF160EB2F64BC8,0xDE54443417A80FD8,0x4F11A4A2F83A2DC1,0x72443A029F020FF1,0xDA565E6204722124,0x48EA9427F68106D8,0x4BBEB54E19015FAC,0x68ABA9087B2347C6,0x79BD59F1E7BEF37A,0x92CE3371DC7FD90C,0x3A77F3F0DB59FA29,0xF6DAE14EFF255A83,0xE84679C6146009CA,0x3A6DEDC6FB776576,0x22FF60EA0827EEAC,0x59EE9BEE941C7391,0xE1BB03AF2A72395F,0x941FDD5F418DA680,0xAF9DEC9CBC8E7C9C,0x67C95297BDFA3854,0x97F811DCF0EF2B7F,0xE566CA0B0C7BB35F,0xD7921D0AF5F09687,0xE345987B71C25272,0xDAE1F2A9AB55F88A,0xDF7E7B1A2F495051,0x20E45BD6C9D8E1CF,0x84748C03C435475D,0x02FBC914CB0424FC,0xCFCD568929D81036,0x06998B201F88C949,0xFBB134C2C8287E0B,0x1C99C27A05FA1DEA,0x4E07D59849F63E9C,0x1A311F37A59577C9,0x8736F1A1A02FD7AA,0xA2C3BC29EFE31847,0x57ADF7E4F63DB3D7,0x5F419268025459B6,0x1FE50958A2D19405,0x8125DF3221F9724B,0x6839251160916505,0x59CBB74760A321C6,0x15FA1B783C3C4F28,0xD64B4A22C668881B,0x33D068EB6E9A4FBA,0x124A03E590E6324B,0x6E155A98A06B0F95,0xE7067BBE094C67BD,0xAE80A15B0C5455AF,0xB53EB85E0EE93FC1,0x349344401A4DFD9C,0x52BFFDC33180ED92,0x5CF84A36D20776A6,0x19A69249BBDD27C7,0x04725621018ECF1F,0xD1526BE74EDB9531,0x2F9BC1CE003D4A38,0x190BD4B6F9D10854,0x152DAF4354AFD2C7,0xA8B3AE5D0A03EE12,0x47E2EE4F5919924A,0x50B7CA6BC5C15C6E,0x75C03AC60CB94D59,0x7EF4B84E20A174BE,0xB6492F12D3A27A52,0x9F4CDB6DFB7BF50B,0x8E6D1B76E800DF1E,0x09D212D4C22CED88,0xBFABEA9BC51E2B8A,0x453C174714BFFAB8,0x433B901662F17295,0x179C05B526C81509,0x8584CC6832EB16D7,0xEB5538C4AA60450F,0x0C56D5CDA0104EDC,0xE7CC9FDE6BE7986F,0xA37C74D463BF9AA4,0x5C75B38BAB5DE1E7,0x3E4CF95D01EA8D70,0x6075B19742685454,0x701507B506C02F92,0xD23846F359C6F535,0x7EFF35D4FCDDD53A,0x47D2544ECF6100C8,0x9FF8D6FEB8795DA8,0x31C67055F3111564,0x394A721E736E8E9D,0x24AEFB974529A061,0xBE17A0F596663306,0x8846B2D01BE80E7D,0xC5D5BCB6F399A5F0,0x96C0142ABA493835,0x553D5D2E69495AA0,0x72421C31D4AD8166,0xC2CE22449F7A94EC,0x6B3F72092A5BC399,0xE0387E7C5F917A02,0xB615EB3036AB8A71,0x1DB1CC58CF6E2AF7,0x1AA75FEF3A49264A,0x6BC6F93FF9835AEF,0xEFBB01B033DC855A,0x9F8DAB4F15E55485,0xBB49D89578D0DCC6,0x1457269B09D12AAB,0xDE4F195E6A26E2CB,0x41030149E002C994,0x6AD825615DEE1667,0xAD854F631E08DA52,0x881A41EECBA0FCCD,0x5389950FE6C1B5E8,0x0579FF8BA2D27009,0x4490A8F39988A601,0x410AB067E98AAA50,0x06A12A903A9FFE77,0x9358136D8E0F39E6,0x018FC918D2828E6F,0x0C64501021F2A2CF,0xFB22AA6ABBA8D7FF,0x81D79607D1C48094,0xF486A3FEE597F390,0x9A80EC0423B2A54D,0x4E0151F3733BD684,0x73BDCB518A503DEB,0xD66C58A96C15ED76,0xF5DDA39979C9609B,0xD890ADDE2CBBACC6,0x3DE9D391F4CDB0CF,0x0C9AA81AE40B55A7,0xC527FABFE2061588,0x65E4692B73B99794,0x44D1E53BEABE5637,0xE6C96040FD4231E0,0x44D5A50B4808FB46,0xC3531009AF47B531,0x7F584481EC53EC90,0xD422A5F61B3165BB,0x4EE3A49E665072AB,0x7B9B12DFFDD24ACE,0x9698F7C701199E58,0x91FF705ED4DA8C8B,0x7BAA47BEAB7A7D8E,0x3BEBBEE5FEB4E80A,0x854CD198FD062B49,0xE48BAEB2CD047078,0x49609E85EF4B4CEF,0x9A6BB5A42551E137,0x551937EB383CA900,0x56EB4CE69773A79D,0xAD6F6E240D4993E8,0xE3DAB76ADFAFE617,0x41558493C4458354,0xFDAC330D819AF635,0x1FA822A771443490,0x1CDF42DE2C0180F4,0xBA52E82C2731FF1E,0x4CD60ADFB4E20D24,0x07B9A87F13536252,0x747EF6B19FCE0D7A,0x89181AC3525BCAC3,0xF7F7698531B18B27,0xD7B12C6E6C3B8ADB,0x2FB5BC9CA206C23A,0xDE85E76895AFAFFB,0xFA40C1130357EC36,0x32982434C24274D2,0x97D656C416F94C29,0xB3CFBEB5F1AD7199,0x99B3EBDD70BD2952,0xBB97F59C66B343A7,0xD0043EF1A91248C9,0x59BBB66A8BA2D49E,0x38F08B197F1B02DA,0x3065C19F89C22125,0xAB93E49B8D19EC1B,0x6D5BE62A49EC5076,0x46C6566DACF33B96,0x88F92ABD198BB24F,0x87D9ABA0FC3FDB77,0xF573C1D42F1CB278,0xAA1C5014E47185CA,0xBEA290542AC49AE3,0xE9AE4FE77DF5C5E3,0x312386B003AE6601,0x92987424C00C1C92,0x094B561B7D5B69AE,0x1BA1755B37A08B46,0x8EBEB639E5E7ED5E,0xFE5D9178778703B4,0x026179EF85A7E4E2,0x00E1B2F84CC5C2A3,0x0943D9A6D4D760CF,0x18BD4ED99C64AB8F,0x25569ACB1678DFA6,0xECE6A45B2DB4563B,0x50E9D137908063DD,0x8C8F4495D96FFD42,0x37FCD2CEB45C9042,0xBE83643C4EFBFABF,0x91DDC681CDCE656F,0x501A9AFF54289CDA,0x97FBD95A168B878E,0xB47C609EE87AA973,0x1DE6FB33AE6BA949,0x31D33EB90F71C341,0xE7CD2E6FC408B63A,0x57B716050BAC9A9E,0x1A813FE54C7F8623,0x80CB849CE4A808EB,0x9D1E0E47EB7B1B44,0x4C1DF84CDCE929F3,0x22FACC0F74F2674A,0xDA128785721D5991,0x596A1575754A2646,0xFFE798BE251EE02E,0xD85C4E53A0A082FC,0xCBB3821807E65DFF,0x195F39104790392A,0x6B92A3132A1D9765,0xB0B488AB3EA3600A,0x9B7CF706EFC760C4,0x4FEB5454CA6FA7BE,0x1E8760F2F5F4D478,0x4FC506D4389C15DA,0x12E9C113D28F389E,0xB9D86ADD9C0DEA9D,0xB9877142667D4700,0x72D73713ABF8CB17,0xEEB2744409EC06F8,0xE88C30DC5C6E0D8B,0xA6FFA4CCA1DEC01E,0x07407113FD78A602,0x0A9475726308B0BD,0x1E4641298D6DA62D,0xE091C155A1DF6205,0x6DEBADD25D88997C,0x9EE3CCFE6FB1B217,0x97934E2EF580EF67,0xC9B6EA4E1F50CA6A,0xCF8710E6992A5DBB,0x763C83CBB00845AD,0x9640A0AFC71892D1,0x35AAEE6F8000FBBD,0xB1D4D335B8FA2982,0xAFE5B8D4973A31E2,0x8E445187908F108E,0xC4378E6AE27E6654,0xB610DB3C412C7B49,0xE462E0CC12B18A0D,0x4AF87C31B40A11CF,0x5BEC43486E625A6E,0xB4B15DB941C419C5,0x890A75BF6608A69C,0x8153BE882D5F7C07,0xAE50478AF7022FB7,0x3C22A41DD6DF3F38,0x84DF15EE5F5BFB15,0x95D39723E6F9ED8C,0xAA554268C878135D,0x37305814F63B2653,0x65F98C001EF0D849,0x556B0BCB2A3B3BEC,0x6C77E012914C6E86,0x1529AE8250B2BA4F,0x0363B1D4D10E401F,0x4F54FACF85551604,0x604A80134CD737AB,0xEBA16DE8A20E208C,0xAEA7EF0627CC11F0,0xFDA584B6F9947D14,0xFF6577E754332C13,0xA1CC4A8DD374D2E0,0x505164717C40E038,0x6CB4A100DD0109E2,0xDB534131560F2F40,0x0365BFBC7D46FA27,0xFC34637BD6810BFA,0x9755707C4544FB4A,0x30D9222ADE3B970D,0x2B3FE388728CD021,0xCAEAF3325BDEF896,0xA9F356D0C64E646D,0x6C11A781B7A15987,0xC7278E7C378E9807,0x893EEEDB36FC45D2,0x6474BE9216009048,0x27321BE8BB488D87,0x981BFF0A00C0A24F,0x809F637AAF1ACB25,0x2BC962B792358E08,0x00B1481DB02FD8BD,0x04A79FE1FED24E81,0x1D0152654A7B14D9,0xDD5AB802D14EE9EC,0x3ADFBDD63B9283B3,0xD950D82B4AF5C3C9,0x9C832C5C99546F74,0x7C29FC01BA01C9F2,0x28E1CD07D469D226,0xDF7E7E62721740E0,0x3AC6AEBF03134FC1,0x2505E7C75D354CB5,0xA58BED8E9C655A7C,0x6136278478486E27,0xEFB86BC1245D929A,0x0C85315594E06299,0x38DD112E269CF532,0x081402C9F40BF081,0x511D34AAFC305D10,0xD343F8A4B4C7075E,0xF4730AF8EEAD2813,0x16475B2A010D42C3,0xD7659714FD6F55C5,0x540B3CCFA8E640D6,0xA04DD53A75924B37,0xCF69C54BBBFD9733,0x5C362E34D2F874F8,0x40F78694988A87A8,0x0981CC9C6B6AE157,0x4A07EBEBAA7CE375,0x6FEA99B594946472,0xA12275227254F6D8,0xC81BA14F4536462C,0xFF8E697CF7FBD9F6,0x64542EE5C1FE7FE0,0x12D5796D5A16E433,0x8C9C5FFAAD87247F,0x9B0FC85EB6EDF157,0x9110E0FAE592E94F,0xF1FA5B22DF35CEF4,0x0F604A88B9995559,0xD36F79FBFF67C636,0x9062919D8C2EA838,0x8BFF02720388CFF2,0x6ACFE6612D124444,0x02C4A0732848D5C8,0x58DA97CB4BEC3264,0xAAA56BECA5C1EE8A,0xED6B5694A4DC321A,0x4EA2A8557B7C482E,0xDD9F79CD5682DD60,0xE9F4DF96F55382C1,0x6A77418C86B8B4F5,0x3A1944E87637D5A8,0xFDE21666491A92F9,0xE347F526ADBAC1FD,0x3D0EACD08A61DD06,0x705C7962927DF328,0xCBAC07878E49241C,0x94372CAFFE8574A3,0x9306B985462D732D,0x4A5E787445476ABA,0x64D4D358FD2B1266,0xF0D46DA53B008514,0xBA478B4B440EC2D0,0xFF22567AFCDDF146,0x52A91BE4497B3441,0xF9F7F4D91C4E28CF,0xCE0977636A168CCF,0xB969742709C51107,0xF2786B26D75CAB4E,0x416B57A3353DEF2C,0xCCD1EAC73DDF0288,0xA53E641C019639AF,0xFAC0A7169F36CA52,0x6450CD79C6CC5308,0x36CF904E51540435,0x65928031C18E879C,0xBAB99EE935AED9E7,0x6A98C2BCFE741C56,0x998EABA8EBE60350,0x40BAFD179926946C,0xE7021469595793AA,0x7AFEDFBD7D5810FB,0x979635146D3FE5E0,0xA3C7D10D2C1F6444,0xA5A5CC5C12BF069B,0x793181757FF44B84,0x364AD6C1E5B0CED5,0xA10EB2CD41B9A58A,0x18E9091B50515B61,0xBB8EF36B0E2AE1A6,0x81C2F8A6361F3CFF,0x8B0B7D5F3647DB7D,0x57AA18E9668F1DE7,0x88618CF15779B9BC,0xA96E91E4716E10B5,0x972BCA5A84F111A2,0x42CE24F228D051E3,0xFE0A205A8859F477,0x82CBECC93385E3A3,0xDBD9378D8F8E23AF,0x928AD42810AD8C68,0x8CE2E2DAC1399AFD,0xE6EF6D4C6FFB438A,0x59FB5FD06FC2A1C7,0x874DB08B0D9964C5,0xB08504FD25FE5703,0xFD489F276D770E68,0x604FF8105348A80E,0x42F06764B3019232,0xCA222A1C47BD5ECB,0xF6512208E7E46D3A,0xC7D2D7784E5579F3,0xD839C386D3340C4F,0xC326B48CE35EA0AE,0xB10A0B5152B0C600,0x1AD44E938308E113,0x4E2CBEF2C4F4E1E8,0x5FBE87F898121A50,0xBD1B644910013A95,0xC5B1255A5072F986,0xAC2AD54E0238659B,0xBC53AB855F19F1E2,0xE594656DFC636878,0x54B8E1909DCC3CF4,0xB83C71E180A0DB9D,0x48246FF2C8B04F6A,0x6807387FD3DEE072,0x59F9B8638D7D7D75,0x718B2C205BF38AD3,0x9E47E167070093E2,0x01A2DCE28B7D6EB5,0xEB4CDBFCAB8BA44A,0xF61B351A51A983AD,0x2285DF5F209198A6,0x5D2A7E2C3F34AEBD,0xBD1E2930C53AA5AB,0xF0EB8327D2199ECC,0xAD691BE9A6EA1B2F,0x0115D4FA3C15F829,0xF324419A889006E7,0x00D4E94F465C9188,0x06D7D779F9ADA938,0x595E61E5B6157C66,0x1550CFF81FDA4D3A,0x6BA7C6160E10FD18,0xAD0AD77ABCD1BBC2,0xA599ED259CB728BE,0xEF2E2995567AC146,0x96F1A53CD6F4FE7E,0x0750B121E3223D51,0x539473B78CABD722,0x430C95A504A6E41B,0x54D5933FB627C10E,0xE19E775729AF4256,0xE223404E500FA06D,0xAEE5C2216587253F,0xE5FDED3B5ECA56F3,0x843EE74163608B3D,0x96DB5E9423720E00,0xE9C5B0C752AC3C4A,0x9641711CBB65C627,0x0CBC4636E0249415,0x6EDB7837DDF1449B,0xAA9841C8F21FC820,0x181851B2BAFBAEAD,0x02339E24A3169A21,0x1368C3B6360FBDB0,0x3AEBCAF7613C295F,0xF9AC9C44711C3687,0x4E3373236A3C04E2,0x2EC25B8E28CE228B,0x62E2B32D56F5550D,0x38A485C8587B8241,0xBD840F34E70E8E70,0x237F366F72DC4DF4,0x6A27CCE9EBFD74BE,0x43CC595C14E88668,0x39AF2878919187A7,0x9077EF97350BFD68,0x34BB665F1D12DDF8,0x6760F9F58DB6665C,0xB64EA8580582FDC8,0x48602F8A16A27A9F,0xFDB4948D005EF25E,0x3AB3A1C2F7C15264,0x046ECF327E09E4DE,0x0D4B80E1052A6D70,0x89E1DF504B42B697,0x87830BD976C35171,0x8402C001154FD403,0x7F867369EB1521D6,0x854C2421D1CAE576,0xCF710B63F2F65898,0xD86288BD11241C38,0xC222ADB50EE08F76,0xEDC60E6E883007A8,0x80B96BDD7E8496AE,0x987DCF763D05DE9C,0x9E601F091066117B,0x2EB643BF6A22E220,0xF16CBBF718F44193,0xE2A2953F6BE1157F,0x5A6AD38E6E8B6A6A,0x17AE9FFF7D7410D7,0xD4963C266C847BF5,0x3235EB1A4849F278,0xD7767BB9DB9781AC,0x794F26C4A6C48384,0x88DD0081B4BCCDCA,0x34887F8254B3C81C,0x1F8BD9795751D220,0xB3761347A93073EA,0x4DE216FCEBDDFD7A,0xE81C43BB64B73A60,0x8327FFB9046E3635,0xE90E635F8A647FC4,0xFE46011A8B572B6B,0xF725D65C4997E95D,0xA6A769971888887B,0x059FF8E1A95B9C97,0xB1C66BDD47B049F0,0x248F2E60B5ADF562,0xA1FBC88D9DDDDEE1,0x85E277B16B5BFB67,0x42607A43B03CBB54,0xE86D0DEABA51A3C6,0xB72A643537865E0E,0xCF265E27FE3FCC28,0x19957CF80E368190,0x7C345429CB1F13FF,0xE239847EE6C868E1,0x4F5900A8FB69D0B2,0xC3046EA49C6193F9,0x7881BE41EDC50F05,0x853A94E5208253CE,0x181C2923B333D09F,0x1017DB07731A8937,0x77F0D3636C1A3B9B,0xB9D5A55B8493A99B,0x7B96B418404DD489,0xBB261388D322A39A,0x7363BA1811B4F5C7,0x74BE0C185A436E3B,0x953FBF7F40DAE0B8,0x9C779F650F1B1A7E,0x831E873F71FD2624,0x26B5BDBCF48426AC,0x45EB1532532D85AD,0xE830393BEA210069,0x1E6668FC3A32029D,0xF075CD4B896FB3A1,0x3ECEC93FD3D32066,0x8F494D2AFDF41C8F,0x2090B79DA1DEC720,0x13DF453284F48580,0xAF6349C02EEA99C6,0x1011181AD9C5677B,0xB24D2C9D64DEA793,0x2910AE476B9F1F01,0x911D531D84F6613D,0x8C087B6FA2200505,0x9C24761A8D85BE46,0xC66854C930F18BD3,0xD9D028BE74BFA0FE,0xF197523CE335814D,0x5B44C447BF5BC0A1,0x0DD228E033C5B17A,0xE4AD09529DEB6D3D,0xE107EEEB7B56F717,0x1F556FBD5F972747,0x5387ABE62D7F264E,0x052344198C4287FF,0xF196EE1F7CCFE9E3,0xD9B5BDD1BD33E8E1,0xBEE6282844650E76,0xE284654D26172CB8,0x78B25A16009095C0,0x3CA09F5F4E78D95F,0xBEB0844B68C64CD8,0x59562DE60AB3E43B,0x526EA3B40702BC43,0x0B1D15CA74ECC20D,0xBD0DFD3E498A08D0,0x7E0541E7A06537E7,0x7885F95A20EC0205,0xCF803318CFCA5CBA,0xCAFCA3857B7F4B67,0x3C11791CFAFDB139,0x3542AE5B662FC4B4,0x351DE9D0934D2B17,0xEBB64DA236FAC4D2,0x6EFED13C27775C8F,0x4AD9C25C8EF4918E,0xDBD5E888DF36684F,0xB57FFF284EAA976E,0xFED0EFF158925887,0x20F344E7C5F2B9F0,0x32827C3C15089D8C,0x3270E25573A90D24,0x1027ECF44CD9E4C4,0x630C42D8A359CCA8,0x76ADB3FECFBB29C4,0x85C3F0F7163D6C45,0xA104F75B4703F5B3,0x1F13D5872C7A99DC,0x19EFDFD2A688CCA3,0x54B730D073081A4C,0x784B84857260DA9B,0x619F58BBB5076D9E,0xF6D31746CA5C5025,0x7E904B94FCED4D8D,0xE534AB8D79CD48D8,0xD1C2DF437EE1FEE0,0x703C967139237AE4,0x6AD16738DD434B9A,0xF5693F28CD26E5B0,0xFC5FE43E701A7BA3,0xE629B017B5D78CD7,0x1C4BE7699F28A8C3,0xCFD2573BE87E7B51,0x0665E267B9D3C27F,0x2747FD28BE135963,0x5333533F60CEA753,0x807A12534CE077F6,0x10FF26BC89C841A9,0x8267ADF0637E78D4,0x3DD9A2EF52FD6692,0x2A74394FF0E3A576,0x51D1B57E4479C580,0x2F4E48C95DDBB824,0x164DF7648CD03AA2,0x025CF22BF2BBF806,0xC14942946DA8146F,0x66A9B545C9068FBF,0xCC27AA3A460E8917,0x55E67C40AF8A9772,0x7DA34C7EEB319AFB,0xACEFE4D1E2188D0C,0x86B8EDF1C7721B48,0xC7AFB5AF3472D0C4,0xAB7A5F6C376ABCDC,0xF7251BE988C04286,0xD46696496A676EDB,0x859C4FC860EC288D,0x49EDF5A6EB2A22EA,0x59D0AFA63CA2D7BB,0x33D21570BE444E86,0x32CC9D7C8366D22D,0x4F68D47DACAAD233,0x11013D73F5136D83,0x0D0CC256FDB01215,0x103BA93F2A031271,0x03BC2B5F6C3E5ABD,0x38C636C9505D4A19,0xEF651669127835EE,0xF5C2020582070A3F,0x71FC8C0231C86F1E,0xE6D74415544E6EB1,0x7F2D8DDF5602230F,0xE88F50599462A7F2,0x940E08086A34CF2E,0x9F89825BCC7D44A2,0xA33DE3C4776A33D6,0x40D8F4248E33AB0C,0x5ACBB184754238FD,0xFD6F4671AD07E3E1,0xA5AD88F479FB53C0,0x6AEBB6BE60BF55BB,0xA4A59199ECB73FB9,0xA922BE2B6AC3E019,0x10C3C5177C5DFC64,0xD66E0DF161D2F186,0xD25547AD3E540094,0xEE7EED955AA35636,0xBD888D1A8A83A046,0x42F80757B929E2F0,0x52832B2BA1E3A5BD,0xF450F4D955125B19,0xB5FB20E0BB816A44,0xC5DC59C8EEC3E6E5,0x2C36866D169BDC79,0x5C7EB9E089B0D195,0x1E2EACB83182FD3F,0xB42598142A7A3F6A,0x4F1B6777C5D2AF19,0x2D459898A96F83EF,0x81A7CD2378CA78AA,0xC223B236F2594DDC,0xF0F1EB0FDFA536C6,0xED0901B4F28DAAD6,0xBE8F85A4846271FB,0x353D3D6819F77EEB,0xA73A96A62D723DB7,0x7F48DC72BBFE1058,0x70CAB54CADC49771,0x25E34604C5A2959A,0xF0373D73EECF7711,0x97AB478B095200F7,0x35DCA9143933FFB2,0xA6F2D5260794D0AA,0xB4E561C7E48D216E,0x7079CC422B7F0506,0x9BED7E5B6D611FC4,0x3727D522B3AE0BFC,0x4A856646C03D8BC8,0xFE97EB5742642062,0xED23CD7A90F9213F,0x9B9F722CDA8E89C3,0xC8E1C85637D0AFFB,0x3D4482AF84C2DC20,0xBF3149BE5014CF0B,0x02B2F3E31161446A,0x69EE53088DC1FC3B,0xD5D04EDD6B91CC38,0xFBD793BCBFC9AE58,0x51222F1FEC6AFDC8,0x6E2D348730963FD7,0x9FE49F3611F867FF,0x8CD44DAA2E65B181,0xCC3644650E89C2FC,0x706B97184E55A7AF,0x9219C005F07902AB,0xD8766D0451693D35,0xBD0CD92E3917308C,0xCF7955DC2F4FFAA7,0x153552C31C8E1852,0x37E31936D7C90A0F,0xA7285AE8F5AE956B,0x620073C2967E342C,0x2319EDDB166F4761,0x1C7B2F2ECAE00B8A,0x8666520E31D5ACD3,0x86F4A2F5B1342E79,0x3B3E6C33B332BDAB,0x5BD90005B898A052,0x646BF1A872846D7B,0xE3A14034CE95E1A8,0x69B3CC0A1BE03CB4,0xAB768B46A9DEE559,0x8A4F0C488884656E,0xE7E9D0BC33D39FE1,0x6434F9D82730B837,0xF318C6560CB8B7B3,0xBEA417FD4CD6FE45,0xC3EC7EBFAA08B46B,0x1150739E2264A6DC,0x8822DC424658B5B7,0x67C8CDC7EF571DBF,0x76AC621F6B9A1C83,0x89FDDD225BA853F8,0x6F41FE5ACEAE2509,0x6A2E5F63DC28430F,0xD20031D2149381BF,0x5B3C5342E2B790A7,0x62B8C80637FD7AD9,0x1D582C1C1E8B6E8E,0x6A0620657C1238B9,0xE2B6C48EDCB01C28,0x0848C13BE4E5AEE8,0xEF0B45E59155684B,0x7B90008171B4888D,0x91E6407C503CBE34,0xC2621EE46F149996,0x0C06D6582B3D0873,0x03964A95C1A484E6,0x97FF0DA9BEF1F965,0x774D20E113C3771C,0xF695DB5A6177B98E,0x98639FA162D42073,0x6AA2FF7D4B134AC6,0x916401BBB3C7F69B,0x6D1DBCE4DC5678C7,0x9451B6CFBBF869AD,0xAB9213AE030C4E51,0xF29A483E4C9764D2,0xE5989AEC48BFA62B,0x85FBEC194A340D07,0xAD93C0E797FBC6EC,0x6AA6E82B718FF61D,0x93A647BB2CBFDAAD,0x29E25F44489CA37F,0x798E68B8E8BF3122,0x3B07AFDA8CD1DB0D,0x0D7B1995880614C5,0x27FE2C484E2410D6,0xCF0BD9E0502FA1D6,0xEBF7DD7B309555F2,0x200FE728036E17E8,0x9F91B5A6258ECFAF,0x0067449F86757C27,0x7B6AD49EF5406DAA,0x76E88EE18961E193,0x89C28012EFB08419,0x24621F10E19E1D66,0xB8335C517115D270,0x5F8EB48A149DF0DD,0xA876F7F01469C906,0xFBD607679335566B,0x0D959AA77B204B07,0x925245F23E2B2294,0xE7906233774031BB,0x5FB6D2D20235FEBB,0x2F24D0B0B146DC18,0x467062D68BAD9A67,0xBA8E333421A5FA53,0xDEF27D2C7D23D06E,0x3789944F1A355F33,0x09911EBCD46967CA,0xF0D3018AD0008EA0,0xFA5B4B7F309B46A6,0x210DFDC757AD9007,0xDEE8710FDFC754F5,0x684551EFBF0DFD56,0xAC3A334F666A91D4,0x7007FB85AF1F663C,0xD2AE36C4DFE04500,0x16C11E9BAE3DC7EC,0x92D471CCD43B5AE5,0x289E620C48755557,0x2140EC25BB882D69,0x3173303B60C26EED,0xE0A79928ECA3DFF1,0x9DE9A945AF95F333,0xE344E40889FD0C59,0x7DE3EA45B6BEDE3D,0x3E8044BBD021AED9,0xDE4AD110963499FC,0x9AC77D56680C5953,0x0CF4444C96CED8BC,0x2C8FE53B83014278,0x564D53A551400043,0x4A9414A7A5935298,0xAFE8734477D6BD20,0x6AE203EDDB611534,0x30A1C4073C054C09,0x61FA3412C9BE67C2,0x926E7DFEE3429235,0x841B349447C2D213,0x36348A7D727517C7,0xEEC02A0B5D37F0DF,0xDEF7571FABBB1C10,0x98849B85F6D69029,0xA767E0AE0DAEDCAA,0x2DBBCC653C8DCD1A,0x67D4F50C3D28AC00,0x04DB38B66BC0C754,0x0F9FB14B16A6A005,0xF1AA78F61023C4B7,0x8FEF1546A98DFDBE,0x020D052E56426DB1,0xF7E3B13EE3BFDBA8,0x6B558EA63161E072,0xD8E0F2836B27F012,0x3EC03B6E56F01DB7,0xB7DC899DD81F54D8,0xFFBBD9DC50DB1D67,0x9C5F5266E7B0648A,0x5D832BF36B1D571A,0xCE52AC3E28CA4DFA,0x65D09440F4A434A2,0x5F2E2805DF309734,0x58714F581AE43834,0xD12BDE06473022F3,0x7C83F8674946C278,0x5A5431BB92242277,0xF40CFF540C6674D8,0xE36BBABB3467E134,0x1D421EA4598C9886,0xFD5E4EC278CD9893,0x1D20CC40AB62798F,0xC2419CFE83556AC5,0xCB91B5CD214E5B52,0xCDC4F439E464171B,0xC24E5E13CAB56AC0,0x655DBAC5E20317B8,0xBBBCDACE9A34C9CE,0x2C3607C1E2BF50A8,0xBD3C38FA476B4290,0x5B0CC316B6B74DF0,0xF7AF0F61FB432A33,0x28B38278AA9B4109,0x86DBDB1DCBC97E12,0xA387A09E2483D367,0xE5D619918EA95CB3,0xF6644F1C13520287,0xC560F936486E7736,0x45DA50529DF44A57,0x2D3A2C5DB914B388,0x7669474E946EA257,0x2B851AF6882D0383,0x400EC3B0AEAC3C4D,0x7271467A79451F97,0x0C655253DFA163A5,0xA962E5506FF2A7F5,0x876964E4B76F2DD0,0x31400733CA2CF788,0xB52AD6F70FE174DE,0x5FD22A0E70F4EE39,0x54BE8F3477B108BC,0x2E0A80EE25B16D44,0x98A73A28D4E1C745,0x53F73DD40E2A44AB,0x4A067E189DE8D893,0x8D3965C7CBDB9373,0x2E34B6FAFBD6F574,0xB2FCF53B1B223001,0x395F46F621B1A260,0xB7EBD2B278C41C82,0x35BEE229D443977E,0x9021A86A56B1721B,0x6A289F7E39E084CB,0xA62B80FF0907A30B,0x815747CF85E6F271,0x4697711654354CDE,0xFC9F0FD9EFC70853,0x67F1F46AED816208,0xF921F5AD8D5D0742,0xEE8AE6F17A9FFA97,0x84F6CA6B0BF19198,0x5B05F6D4026C4151,0xC474EAE1FEFBE73B,0x2B982B713DD575DE,0xD7ED7486EE579125,0xE626E0D09AF9B719,0x26E096497E54E125,0x4BE2A3B50030AD45,0xA56A5F1327334DBD,0x46ECAD489F4F8F61,0xBC979FF34A0C1D0A,0xCD87A38C583B7442,0x4E7C4ECDE24E42BF,0x86A641EAC6A802AC,0xBFB44BA1BE6F02FA,0x585BC8FC4D11DE89,0x71750887162557FA,0xA698D67F585BF638,0xFF7DC0663C4693C1,0x9A3FAD7C6C4C2B9E,0x610B02433A25D78A,0xDBF93B7757C5258C,0x8E93736CD77AAFAC,0xC74C10935B2A752F,0xDA913A870AB89EAC,0x87DFBA3A6DEC9233,0x878A81499D7B73C3,0xFF279EA55136CF02,0x6F63562E35AFF90C,0x263E863BB9DFEC0A,0xE064738B0E5F37A9,0xE3917E496AB52215,0x58B7EA35BC9CA976,0xE6F02D7C7E30153D,0x3747F25D2D293A40,0xABB076054C7B37AD,0xFADEBA48C9D8A3EA,0xBA65D7226D9B00F5,0xB2AB016B92AD9174,0x7F50C7A2A9854C1E,0xC5F2D11926096D45,0x40D7FDAA0258767C,0xC1924611DA85405C,0x1347F36476801F33,0xC1B3164A99D7ED9B,0xB4891F78E7140C1F,0xF8318A9CDFC43B71,0x6ADA28B4B9835F46,0xE7769EEDDC539F38,0x6E32CC4337E8AF6D,0xCE635527F8FB1FF6,0xB40B538B6C124328,0x17184ADE506358C3,0xA98AA3BB0602FB28,0xA57E3085D9615122,0xF7BD75DA9FB8F914,0x546368F146348901,0x6E1255FF530D67A0,0x82B3F951BE3C91E7,0xCB57AC096E19F1EC,0xCA805BA578D62A15,0xB69440F262DA14F2,0xB7ED420189D7296D,0x54FF502AD1BF0D49,0xC5477F2274ABA530,0x807C3AA6E3DDC935,0x24BD5A20380DD727,0xD7ADED2C1B581BE6,0x6513A5AF746F1579,0x09D48CF582F9EBE3,0xED0FEB7EAC50CC41,0xAC32FF8218D8465A,0x1E3167EAE44892DF,0x03BF8C1958268558,0x79E2AAB993804E5B,0x69E7DE4681022457,0xEBD8D89217788E23,0xBAAA5530EB89CBC0,0x8FD7466C3882ADCF,0x4C0BF94D340C903E,0x3E144724887EB24C,0x8C7789CA3DC92933,0x205544F3D6189A6E,0x1CCF8D96A13BF014,0xEF75D1C9CB2D1EB1,0x0BDEE173E93E66F5,0xDC70FD84F9384C4C,0x9CBF4AFC60D4C75E,0xAB5E255FB6B70B6D,0x03CAF59F439FEC83,0x00DEDE6768478D2E,0x230F03218D95E9B0,0xD5833F640B450EFA,0xA22B91A6FC96828F,0x12002D70E49A12A7,0x4CEB2286903682D2,0xFC52AF508B92EB27,0x5532ACD5F127372E,0x7D37F831BAF1584C,0xD7A3F8AEA8E2DED4,0xFEF7E8D33783A596,0x41289BE76EA2A441,0x96BC5F48306482CA,0xB0A9B5A73CCFCEA9,0x4D51A3B9877D2B83,0x65C6BD0DA0D273D0,0x93AA344A80D33574,0x2E9A19C3B98A09F4,0x5596A98EBDB469BA,0xEB7EBE5B0802EB2F,0x541D8543E317D08D,0x3D2AFEAA9CA9E3BC,0x75F56C57B4A35837,0x92A4004885870D35,0x61C5CB193BD9ADB6,0x9CCBE78F66406E9F,0x858B536F6BA794BF,0x107F51D0D0510016,0x041F8F848C4FFBD5,0x5F6A84E96641CBD7,0x3486C56D2CFFEBDA,0x2B23EB0DC47421C9,0x865BE4AA1A6F2783,0xC7584732F875A456,0x57604FF6F7A8B58B,0xCBEE7DB44A314538,0x06975751B2784F1D,0x975AA3F13BCD70F9,0xFF4D65487B137C30,0x21211D0425F7A31D,0xF9CA7EC690808700,0xAAE6C5BDDFB75332,0xEA173C1EC52A9B97,0x2F674FAB51C38CFC,0xF8A5DB92B5806387,0x0F4EDA6042B8C8C3,0xC26337AFDC837475,0x4F9014270DDE1562,0xF34692595BDD7434,0x073070DCD6086B74,0xA25BAD5955497B64,0xCC2822C78775CC03,0xC941B2413D2CCD49,0x8A831CA6AA068F3E,0x17A5FF3C8E9009DD,0xC068B2F394F13810,0xB5D4A0983E5DBD7A,0x203E5095C1306182,0x858C33934E92D4AC,0x8AB7AF610BBC28D0,0x7C199E46C0F3EC79,0x3EFCCCD2A191E6EA,0xBE7C30C6DE1D4818,0x0E63629BF87E06E2,0xB999FEED21339828,0x177249EC701E7D32,0x2FAB97BC91C293D4,0x28428991B5917600,0xA0AA87A28167387E,0xBFD525C5EC7E723B,0x57F4060F95408DC3,0xDB4D9012B2FB1D2E,0xBA8038A63BA1E736,0xFEA3CB1BB29D7A5B,0x4ED2473CE90C68C4,0x84CE38B63D863D76,0x54383AB03D3B66E8,0x566C7158F70BEA00,0x94894E41BBF3BD4E,0x0982056DA05B0A22,0x843097452F659BA3,0xDF5D148343DD7DE5,0x0A3F79ED6DB23CC2,0x57E89836AB0B901B,0x9CC6A7B453C39258,0x2C89DDFDB2E90998,0xC666C044C06C4F5E,0x1D9D702A15509100,0xF2ACCAE01D57301A,0xE99C52DA19D1F282,0xF2A403E8ECD1A501,0xB50AAC1ACC329C7A,0xA9A223637E0ECB01,0xDA8B1911CC95F40D,0xD6EF54B7F99F0E58,0xAA9127DAB7DB8833,0x25E501150582E0AF,0x5A2E0EDDFAD9896B,0xE64BE17C49777925,0xABFCEAFFFB93429C,0x72C13132F148CAC6,0x8268176DA7CDBBA1,0x974CA7D28C022817,0x0924A76EB9B432C6,0x7FEDEF3B5DA3384D,0xFF2EE935AADBF6A3,0xD59B103544668FE5,0x977165FC4D2AD251,0x2BFA227426739E01,0x5455389B46C0CFBC,0x7F85282E7DB9AF71,0x95E20AC78377A1CC,0xE42CA4569D59B49F,0x601793064C17457F,0xD7D3091F58DF08AE,0x679D7191D06BB4A1,0x016A3B7344CB1121,0x1B45218EC1A094F6,0xB050A27E955D7C45,0x1D3F6A773C65D508,0xE408DA099A6D13DE,0x7DFC876A7BE7BE38,0x4C0A1567AAA929F2,0x8D380C93124B3ECB,0x4D116A840C3E7E11,0xD77592F5E6CDE06F,0x76103419F643DC11,0x381EA81DC19B45EE,0x0D9EF25A2CFAC4B3,0x9C13477847119E7B,0xCAC56070A04B635D,0x48C448854249FD57,0x06B63CBD2C9AA6E4,0xECA5A43F0B2BCD99,0xC178A605AF9B1592,0xD41C20169C25878B,0x70FEEB132F3E9301,0xF01D87F1E3295130,0xEB8872633710DECC,0x0C221B39C5B47218,0x60A13CE2E31F496A,0x4C75A591E8C04445,0xA11EC45D4CBF7FBA,0x0F555F79876B8CE8,0x4B4644A9F4AE4D0D,0x3CC2F0566EADCC61,0xC1B6F44CFF565B72,0x0D9DD2F07A48EA6D,0xAF89C819AF517FEC,0x4FB802D20026E8B6,0x25D8F92144A3DEC3,0xE5968BCBAAEB5DDD,0xC23A09B5DE39AC2D,0x6F5A1A6F69DCEE96,0x0C99AB3C1133D6ED,0x18E8272810E3BB90,0x33ED73C2E92052E0,0xE3931E0393EC0363,0x6960D4DDC5B8DD0A,0xAC6506A32823F908,0x7FA69486C6BF1C88,0xF2B5FE1F908D6D81,0xA06F313670631DEE,0x01BC17498E666238,0xA8791FEF87BD107B,0x0C4023131FC62475,0x67E7CD36D4805D81,0x51F03070193007AE,0x5EA48AF356EB43E4,0x594A168C396163B7,0x146AF6AEC754061D,0x123AD1D94AAB522E,0xC7F14D765113AF08,0x3F9706C84D4A7E5E,0xC9B4C719E98A7E22,0x42DDB98117C61613,0xB5BC9841580EE1C0,0x57261C738248C575,0x2D3A847211FADD45,0xF760CF095955C3DC,0xA049F4F93D78D962,0x55F423D6775E23D6,0xB46F8D031EB994F0,0x48B2AAD1422DCB76,0xD52F91C822ACF7F9,0x22DFD00B5B96182C,0x3345E75073FA9D9D,0x7C9E400443D4DBD8,0x15AD472416FFAC77,0x5F968C52F2FBF057,0x703AEDD2556E2C51,0x2FABE24E058C7146,0xD78F1D208A6A9631,0x7FC62EA7C6E5F29B,0xBEBCAD8377014AA0,0x3ECD200FBEF8B610,0xA3498BB2F93D6ACA,0x46B03EA843CA03E6,0xFE617509B64753AE,0xB2A828AD7F4D91E5,0xDBF0F30B24607B69,0xF84FF4F60604F3CE,0x9F87F5DE5C09DB0E,0xCA2D460EA704FBD9,0xBC9A248B471BC95D,0x96C8DCB7310DD16D,0xA639EEC3CC7B1C75,0x8C0CBB86AC2F0AEE,0xD94B86E0B54020B3,0x8AF44363D3497E81,0x375D7B340E6E3630,0x66145577027E551C,0x93586BCD1FE1CC25,0x696B854DDBC37DDD,0x716A78EB91795BC3,0xAAE3E35C3FC5E78A,0x3B5BE0B074209933,0x05F7D1B353CB27AE,0xED137E4B1D3AF64C,0xCF3621D71F6A4F1A,0x4683C0E1D1228E43,0x87977F5043F474A2,0x8CFDBA6E01842EF4,0xE11F0A09A97578D2,0xAC81AEED63C63E2E,0xFA09EEE3896182AC,0xA0A92F63187FDE14,0x6AC01DBD53A72271,0x50FFA1EA1C01247F,0x007DD82223ED59A9,0x6296D6BA1563E4DD,0x7DFB582D852BCA1E,0x59F7F06DE3986988,0xC605429DF4A9171E,0x6C104EA5F365216E,0x70E47176636220D8,0x2A5E60EA7D28E097,0xFB69C61A5A7F2626,0x646D82CD80C7D32B,0x1AE492CB8032C335,0xBA985B9744C4FE88,0x703FC03C9A379A6F,0xFC0F46CDB15794F0,0xA5B6F37830C6C711,0xE5E294910096DD44,0xBE9E849164A10230,0x54D5A9DE200F01E8,0x57FEEF083187A038,0x16D446FA8B01B386,0xEA8FBEC72CE85CF4,0xEF75012B2C2974CA,0x68E3938860AE93C9,0xD811E3826F6000EF,0xE97FE4AAAA40418F,0xED537B0263B15747,0xF0C5505346A8928D,0x22181225E0CA08F9,0xB383E5B08D080B1C,0x41FC16823CE4AF62,0xEDF93E89BCF9F088,0xBC28C32AE1B4264A,0x07C1B10766A2CD8E,0x729ECED03B6B604D,0xBC110FAD118A9FFF,0x563BD8E4092AEC26,0x0D7C0271411B8BF6,0x02A04843A4E88D08,0x7E5ACD7172AA5518,0xB2553C4BF1389CEB,0x3B34DB2A0A70BC42,0x8FED5E9B14E147FB,0x555B0096CFB76D82,0x51582F7C94D41A87,0x3A7924DDB37AC67C,0x88E2DEE1CF2FAC89,0x4406EDF3C5028A43,0xFD55093FBBE37FFC,0xFE16A6CB6C09FBAA,0x74E48DC989AC4140,0x9F13BD16E06AFF68,0x79517BCA2B116364,0x85D878BE7F91FB3A,0xBD92697D0D8C3E1A,0x99461210A76F579B,0x34590D18147DD91E,0xB46064A0B1FB0F38,0x2B21BE7066F48A2E,0x2409CDD143EA1ED8,0xF17CF21334346457,0xBD554540E6882225,0x160DCEE776546FF0,0x99ADBD0FA210B1FD,0x875FB12329866E7A,0x5E35318B9620ADBD,0x0BB358A8FC3AE442,0x5063133D729ADE05,0x740EC7084F3C11FE,0x1789C4D8BB135659,0x3ED28065F1178552,0x25B9D9DA1FC00203,0x10580F32CC6C600A,0x396B71D54785232D,0x90154A58720D34A2,0xF1633FF855CA910D,0x6D962FF691942CDB,0x0082E202022C9405,0xB676EF19460A8641,0xF1DB9AABBC32462D,0xC1A3C6F38F83D9AC,0xE5997CF27D0710A4,0x2BE4722F49033B43,0x8DA4B150F0382E4F,0xAE35D2A7EC439C2D,0x2C5E874671C49E92,0x5D348FBA9D73612C,0x90CCEE876BDF0FD2,0x0D1270058D5B3FBB,0xA8DB9AA24E0A6B0C,0x1B971ADC22520613,0xFA071CB66C6C1CB7,0xE63EA33F45BCEDD2,0xC5AAC77D20A6FE50,0xE752E64A91A2018A,0x17EAEF70A49D30B8,0x8D66B65328C94205,0x4D054FDE328E068E,0x4902EC6A2BD58B1E,0x19F5C649FB05B466,0x2765C6702E3E3B60,0x2E41567FED53AD6F,0x555642D8D1118EBC,0x87D5D68625272BD8,0xE1FEC541C0AE8B66,0xCE4322F8E0BF3DB9,0xA2810B927C1CE425,0x505451A63ED00309,0x48932B0223F05ACE,0x83BEBCF41CCB00EE,0xB69440FED9C34ED5,0xAEF90DF1C3BC5EB8,0x905ED3C37625F8FB,0xC9BFF32DD7C21065,0xCF7BED743CFEAB0C,0x94E71444D90A1B97,0x15FA1A31BC306E9D,0x983DBD18097AAF80,0x554151C47C3CAB6C,0xA2ECC93D64792780,0x10D2F3B29ACA9E7B,0xBE7FF0AC072842DB,0x7736A16B01A6651B,0xBD0C970F948E2B4B,0xD60C464EF05A6EBB,0xC5EED83EAF457090,0xC11E9E90D4EE2594,0x7483C9CD0BE288AE,0x8B9C327E712B67B5,0x39798148AE6FEE88,0x990F699E37149BD1,0xC512FEA087129BB4,0x10947A2947A524B6,0x6D6F1C11919C0CBF,0x809C7487156364F8,0xC756FE488E7593BA,0x8DC9E8CA7B97EA3B,0x3CFB6A48970DE3C0,0x6CE258B9E7D515DE,0xD87631D7E16CE21A,0x82EEEEA0949FD9BC,0x8041C29EA8F6BE4F,0x8C5F4BFCD9A3CDA5,0x4C3F0781018F4199,0xB07BCFD6F9466206,0x7DFEDDA6F9150B84,0x68138674FA7403B0,0xFCA8E7A9EDA1B195,0x0CE645B2FA5D58FD,0x18C09916794B445B,0x4AA49F2F2C7F8B29,0xE3656AD3FC874823,0x950C4FC1EEC1ABAE,0x98EBBB3C7BE098AB,0xF82AD7A0F537D0E4,0xCE3FE2BE9F1427BE,0x6047650EFD710660,0xCAD0DE10409B8F0F,0x02C30CFEC7ED7EE6,0x23EAA069C88A76F3,0xC4333C67665BDE8D,0x7C55318B11E66AFD,0xDD753CD945A574E4,0x6437FB40BA143847,0xCE9F50D8C8B64FE6,0x2EAEFA31B3A7947B,0x15935252320A4988,0x5F1264776F30D58B,0x15D8837D360CA5B2,0xD07BBBAA179F17F8,0x9941D9DD4425D211,0x092D70A94A0A0C74,0x5503C0F4C440AA91,0xCE94FF79B493FC43,0x8762F15A3ED19A9D,0x7C60196055B32219,0x9EF840B13CA3E160,0x005E2EE4474333AC,0x821C0DEF48294568,0x27BC682F44DD87AF,0x3A7F466304118CFB,0xCD62EFD02E2E788B,0x4E5C489C689ED84E,0x38A2BC621C31B410,0x51F4E54313B3D10D,0x538F2F850D8636FF,0x51A9D90B1D6C99AC,0xBA9AC69E30A42E90,0xC2625722F72A11A2,0x6685D3297E8AF339,0x06B58055EFCEB073,0x1EC663ECCDD2E132,0xF30FD3EE72C4C577,0xBF8E09FD9AC63EC0,0xD3B2C9418D768335,0xEDD30EB60FB78B94,0x775F25613E34FB05,0x4D1E5FC6414A5A5A,0xA13099A78A7C574E,0x8E6C0DFB70C8EC70,0x5F92F7AB01738379,0x392FDA64C58D2C44,0xD42F4885A9FC33D5,0x9AA20708A09881E7,0xBFE414D53F10C2FD,0x738BA7F65D356AC3,0xCD2DEF8F293008B4,0x371D02ED0E15CD33,0x709B628716DBFADD,0xCFB11926802AB861,0x115B29C45B7A6298,0xF6700B9BA1C82322,0x4FC9917FF3AA4808,0x4430233FB9C10163,0x0590B63EB674DED0,0x78DB0C9B95D91216,0x2C2E132CAE2E0362,0x6C4EA976C8E22B79,0x7B8332346E95172B,0xB9F76172526CF996,0x9B0693526CB9F96C,0x386692571F30AAFF,0x179F85D0A4440E1E,0xEA5A645673BCD249,0x7015A5454DFE724A,0x4072D54789C6FB4D,0x00F7C32FD5D15099,0x83FC009787B69D2F,0x4C92FC16EF347E65,0x094C2B05AA12ADC6,0x952290C28E2E0E81,0xAFAD4E9E3B2D254B,0x9A88BC1E2D524496,0x28E21AC93343B465,0x2B21D95A458A6FE4,0x189E04E82F0C223A,0x1519AB65A0D8E42D,0xD29BC0031FD8760B,0xF0A4E4298E69C7A4,0x79E68BB931394E25,0xD80AA0AE8A9373F2,0x7B3282E4F2176525,0x5C74ADA5CFDF9CDB,0x0F76F486EEA3D21A,0x293EB60021DEAEAF,0xBF56561C812B9A6D,0xBCAC4F89ECB5F66A,0x54F54509647FAD73,0x3CD36999EBD8EFC3,0x0C6B3BCF66173091,0x555C6A4C1E916783,0xF80F425633AE2C09,0xAEE39BF4C1D5A5C2,0x30C1CD958672A676,0xB8A46F133E2154DC,0xA46045AFD85F66D1,0x16554B893AEB68D8,0x1394F8CCE8A15C8A,0x2954C4C6F62699B7,0x36FB331203EF9395,0x5E6B3668516BB81F,0xD122D270F68B08E6,0xF97BFBC4E4367BEB,0x05318CD98D68ACA1,0xD1702F3E957F4FE8,0x4DFCDB61AA4D7651,0xCCA276F529A15F5C,0xDEF606755FB691DE,0xD3BED041DC1064FF,0x59CADEA7E909D1FE,0xB39F58E0D10A4F77,0x102D8E7102A33554,0x70C6AD2C1FA927D4,0x14C79C48204AC439,0xF926BDF539EB1E59,0xD68E90C67E2940F0,0xF97CC0CBF7E48359,0x13B0A34E969F9B5A,0xC80D8EB294586345,0x4CC5C1AB6359051E,0xEB2C505977F172F8,0x2DF4055EA9F52B49,0x8B83CF9C33E41EEE,0x6231EAA630F60191,0xF23699E965413A06,0xE361C806498BDD50,0x934A4A20F88F6442,0x279FDF2BE8D6B82F,0xD6D7F935EB7A8719,0x8875FC4F1BFF491D,0xD28409668BB22787,0x0885BB613D8BCD45,0xC9A649E8FE2C1093,0x9C4E9FA1DFEDC339,0x49416E493BBBBC16,0x17E7D293DCDD6493,0x9133FAFC8E3D9621,0x539FCDC1195297FF,0x1EA958586D912EFD,0x3B1DFF5B60B71273,0x67D1272B390A876C,0xBEFA5A18E189BAF9,0x39FC698254FAB089,0xD9A4D3A83CF18CEF,0xC0A3495D81A43D4A,0x45499CE0A7262C78,0xB64EE66A2CDFB15E,0x0B6C7B454F4703C2,0x5E8DDA82D1A9D820,0x2C81322D37BC609C,0xB3C35184CC586509,0x7055C000E077BEAD,0xE8A852FFB91EE8CD,0xE7B11D30E21415B5,0xCA045346EE6E0621,0x45008BCF09A6FF11,0x38A764F5839742C5,0x612DD8489E2D3273,0x93350EEF61521995,0x756818ED8962D013,0xBA5D9FD5F5AFCF7E,0x899A455C8DA89AC2,0x00C6614DE7C2D00E,0xEA18C2B5D248A88C,0x60F85E42E9B51354,0x16C5075132E090D7,0xBD3529164464A102,0xEF790247A887F4F1,0x869779DD905120C2,0x25CD33958E5F82BE,0x52EE9AC5E7FC738E,0x75BA0030779ECD36,0x6F7C0C283480493F,0x17729433EAA768F6,0x760597DBAC77BF95,0x9B12F8F5726D46A8,0x5314A6C2871F0503,0x74DFE6C3194DC2DD,0xE3424DDF4D8023AE,0x098D1E8BD6416A63,0x74A5972649AE9DC0,0x9506CED8C3402B09,0x249CC02DB6A848C7,0x69DC79A38638FF15,0x2B13298DDB530D03,0x578CECA567A2EF82,0xC8220E4B98DCBDF9,0x86F0D382876EF3C0,0x1F6EE838D5C7A1C7,0x355245E60787A743,0x0AE7F3C42E58C827,0x59EE4D951FB42DC9,0x6FFE7686111F7E6E,0xE8F551960FED3C4D,0x03E901833F9627BF,0x937A5C58357B7A36,0x67B3080213CBA20D,0x9755E4185DB1F666,0x83D70751B2E4E182,0x55A26CFE2112B16D,0xA34FB7F9C091914E,0x8893FB3A9FF82F19,0x2B6A471FCBBD5623,0xCEAB0D6A89CEEFB4,0x8A259347145EBB47,0x2E585E1CF219D62D,0xE2D53B7372548E71,0x90506BB77CA9EDAC,0xC1C6F37D80BD9BE6,0x33DEC1D0C6C6383C,0xB8317C430AA4D8F9,0xD235B92C3FBB3BCC,0x2314B72E3AEF8AFF,0x9F83CDCAC5E1A7B0,0xFE8C3125BD5E40CB,0xA500CD3505E3F7E2,0xF500E5AE862C3E06,0xB4F45DE0B9CBBDC4,0x797E76ED977C98C7,0xE2237CD240BBB333,0xF71BF8C93BDC5E8F,0xCECDDB2082419AD6,0x9412DEECE698F63F,0xCF5F55CC7E578E14,0xD97DC96E09FABD1D,0x92D93C3BF8CA1BCC,0xB5C08C457B80AF64,0x3E90A588B038EC4F,0x05DA3BD26923CEBB,0xA06EF236CB9B3E18,0x57AFE057948C7B96,0xD528A78A67AB5363,0x5E67F9613B6DF51A,0x856AE922ABB0304B,0xE895A5B271A9D29B,0x8F0F259776A19C6C,0x0C86C0C9E3D5B691,0xF199175ABF906B95,0xCE06D2C8C9E0F9F6,0x2498EBCEE024D865,0x7D33ACFF0B5324C8,0xF9B204C085059C92,0x399C16E26FAE557C,0xA1C90675B67BEB33,0xC2D92A0AC655745F,0x8A024E7158999369,0x7E7B96188890D850,0xCADF00B5ABCE8BCA,0x9F74D2DC12A5D858,0xE8B7F35FB3CACF69,0xDDBF4449C9056BDD,0x15DFFE7278CBFCD5,0x81ABF3E837BC0858,0x52064BEFA2AFF7E4,0xA8D2F76E096F4B5D,0x216EBC1640E832FF,0xD3FA91AF5AA3E33A,0xE39BB96E02DEBE24,0x394FA221433D92A0,0xAB0AF4A9388DDA79,0x7A1E9DCC3F9BFD6E,0x1D95FC6A2B446CAA,0x34F41ED014C64441,0xB2CF333D987DF5F8,0xAD982E68DDE1FCFE,0xA5A36FBE01E715E7,0x5E1D711048F580B0,0xC7B42D56915B6418,0x1433589F48C68231,0x0E404395EC54C4A0,0xC5970E633D67FD5C,0xDEECCD570224DEA9,0xD2C8C1D54FEDEFB4,0xA390E97588BD2DC0,0x37D49D923539226A,0xCBFEE05124608277,0x0FE00A07A6A8B4F0,0xD8092ABF320287A5,0x9BC9987D4D53D262,0xFAAFAAFE866CB2D7,0x695DE111CC897E22,0xD3CBB1D15BB998BF,0x94336AD4464016F8,0x962595CDE9B58CDF,0x5910640268802754,0x619190DD746130E9,0xAD19944AEF5E8FC9,0x8DF10930F43C7A80,0xDC0974DBD5F36383,0x2707A04CCA9D8FF7,0x2A1C5CD4D5DB0191,0xA76331BDC874A8A8,0x319E20711F32BD0A,0x9B4076DFFCF9AF16,0xF7B0E0F38D11DB60,0xB5F7FAF5C437F243,0xFBFF6544F30CE785,0xC79646D42B573A7E,0x39A1BCE4A06C0D35,0x20A997E9708DDA21,0x383D115F564DFC8D,0x893E30D2E30FEBF7,0x42CE559D52B0F60E,0xDF40DBCB23F02E59,0xF0FE15661E13FE60,0x89E819E69D09F51C,0x236BB23E34B2E48F,0x1D617F7762443BF2,0x11072EB9ADABBF2C,0xDBBE7550AC81A829,0xD8D340C23C74D5CB,0x33277B7EE8991334,0x32AA5823B2EE0E96,0x553ADA06E7720C88,0xCE7EFFA03FBF84E2,0x224CFD1870EA7D8E,0xFF33E0B585793D16,0x3747372A4A50992C,0x693B41B7626244C2,0xA7F61E6FD247ABF3,0x1846F97E5C79076E,0xFA1A994F1DD79966,0x5E3526E912046D27,0x3858769528B661AB,0xF66699EA5D857136,0xE5544B4FEAD7AA15,0x7BEA232046A1135A,0xF65EC8EFB7BD9393,0x8B3B5847032E1D00,0x15973BA125861D24,0x0B835062D864F028,0xCE8F0068F90DB69F,0xC5A25694CB2C4292,0x5CDEAF228E3B96E1,0xFC9A632129103E80,0x17CDEE3BC2F06212,0xEFE69CB1F75FF2C2,0xDB1C6A8494B246B8,0x08D5038D4C2C60C4,0x3E100F164777FD10,0xF18FFB49E7656157,0x3702FD14DB36AAD1,0x2E0EA3A027C356AD,0x49B51CC0239A5949,0xC8209636A3600DAD,0x9CD0CD983A1F2535,0x20C23641A882D4D1,0xCC55F5168BF6830F,0xA10A9E22EFFDF158,0x20E0E8B155EDFB57,0x2FDB8719AFC33AB9,0xB95EC9D582147CDE,0xC806698668FF19C2,0x4A1FFBA4857495F8,0x269F1F2D738EB0A2,0xC17E0C81D8CF7D71,0xBD30DEDF56AE7374,0xC55C709783BC8C59,0x36730A12C6DDB844,0xA8EBF458AF28E564,0x4D6917E5CE19C349,0x840945C059D4BAF4,0x4A5F55D38478981A,0x44B01F55AF8589FD,0x5ACB140BE56334D9,0xCCF390DA63BAA12C,0x5EC148D5CEA22543,0x11B1BD04A7EC882E,0xF7604AF0E7BC1CBB,0x2D72FA5EFDE20A20,0x2448E20DCE71E073,0x1DA59B7792CE7CE1,0xA90D6F77566C077A,0x688DA504E83D8437,0xF689884C92B1E1AA,0xCB809A728A210B19,0xB2505E7E7892F2A6,0xC7A941B792594365,0xE63FA639AC1F9F6A,0x73512496D65090BB,0x056D4AA9ADCDB4D1,0xA41EC72C02F28BB7,0x948208D6D6754824,0xF86D275B51ED090B,0x4E462AB3ADEB1C70,0xFC1088C051D490C8,0x1C885241CCFDA6E2,0x5072D8934B8929D7,0x989EAA21C6E7BBF6,0x0DD799AA53AEAD51,0x9ABF11BE6B1F463F,0x75D88EE0872580E6,0xC45FFEED60C9BF4B,0x2B0AEB4802C08291,0xD29763E138C04E34,0x475A2D3F938C7E90,0x28609EC5FBAC188E,0xCF3CFA2110B04FF9,0x96019A7659B2BACC,0x55C84EDF727D4195,0xA27A4A44B70BC8DE,0x9C4F9673A936693F,0x4F2CCD2213F505A0,0xCD183287DDC4D227,0xA0DDD4FE200E89E4,0x779106F1FDBC3F9C,0x92F99434ACE6AD3B,0xD4ACAE8575214359,0xA21DEBACA18E343F,0x88B34EEBB16323CD,0x4A795C8CA7F68571,0xABE15FEDF83D5AA6,0x9DAFB5ADF2692B86,0xF90C6DD1046CBBE0,0xD87C903D9B6EB8EB,0x5686F646A27CB92F,0xEFF3EACDB1553DCB,0x1476BA2530FB92C2,0x9972778DCF29B03B,0x7814665EE7B4DE89,0xE6BC3F94AB4EBCC5,0xED16C18D5F5BDC82,0x0790465A7C130065,0x4C943FDAF25F166A,0xCAF3F2E0397DC45C,0xD7E7D7B49405CB97,0xBA1687483665FD8D,0x9EDA34A956C59D49,0xC9DD5CD30E730BA2,0x4989EDD6C4242191,0x98019391CCABA406,0xF6DA386ECC32E656,0xAFF858BFBB1B19A1,0x91D153B9C2F884FE,0xE4110DD9C790E106,0x89E931E071213D51,0xD3396D2543C04E5C,0x340FAED56432DAA5,0xD9C1FDDF6B06BF2A,0x1D86C4E57C78BBB3,0x1439AB1DB7B9DA19,0x4DF2AA91421EC65A,0x19086D33CD41BAA0,0x98B7661717BC3266,0x93335AF0C59700BB,0x7AF64A7ECA642C31,0xC3AE2BF8AE54B09B,0x20EC0655E17FA368,0xA8A45AB87B882189,0x77CBAA995E4F4024,0xA0CD84EB3AFEC14B,0xA5802458C528817E,0x8485FA2867CEB6F8,0xCC5D1F9689697B24,0x68572CCD95D0915A,0x272D2EC9FEFE597A,0x712EFAB7E01C1A39,0x651C83B5358901FE,0xE2A9612D9E16F722,0x155F6EF7298D004B,0xB99C4716974BEE98,0x81737D1B2EC7BD18,0xFA51574506022454,0x0808E97BEF3ADAF6,0x2D1C7F91ADD76672,0x447B8556A010ABB3,0x6FF2B42A5087911B,0xFDF681D4F6AEF1B2,0x252BDBB8420C4381,0x04CB1E8E92201071,0x252985D024AC5821,0x4612C56C772152B8,0xA4F6F666DDA13EF1,0x1A56385F0C1B264E,0x545C9769E74F7683,0xF48CD13BB9485410,0x5E6D0DE2F9135C7F,0xE4E1F81CD4DC3A74,0x48F54499A7FCBDF1,0x695AE39F0512FCF4,0xFEB60E50E67F01C6,0x2B96601EE94457AE,0xCF837DBE2B298593,0x4049CDC7CBEBF8C2,0xF34E6503FE24D6A7,0x6DF76E6208961AB8,0xC13E45651C667E18,0x38336042D5096FD8,0x459CF4D07EE3F033,0x3495ABBD4C388D17,0xB1F1373741980E3A,0x44037027E638BBED,0x66D69BE121C4A88E,0xBC056BF63A4B71BA,0x27D580CEA712B2BF,0xF428020DB663ABBF,0x68C81D8FC2393A7D,0x1DC386596B7E0612,0x5EDF50B847C66585,0x51E641A15FE05159,0x714DCEFD5991C8E6,0x8661F53BA7CF7320,0x480A6F69B7D5D2BF,0xBD3D88CAC3461673,0x81CCCF3B39790C5D,0xC0424B066C9FEC9B,0xC6AFC44598A77ADF,0x4E25C3D2E5A8EBB0,0xDCDF234CBCAB9450,0x1E1E0940C9758F53,0x3C86F6FC9926080A,0x548165A40139E8FB,0x364DC6B40A6B6B48,0xE5ACD8C1EADF7FD7,0x5C4AF62D16BC7EF9,0x9B307EFEF79EDB24,0x29452402AEA7F975,0xBA90A5D2A184DBAD,0xC405469D9C0C7FCC,0x2B56CB94935DA4C7,0x59C785A82D618986,0x32665175B4529608,0x5A517DFE7D420170,0x16BD1B7E33EF4DCC,0xB66E70B4A39A38EC,0x94420704AB6F3785,0x7DB8E65FC76BE761,0xC73EFB975E89707C,0x2298BF8657117943,0x0A66A0626B6217A1,0xB84B181890D9C4AB,0x2487598546CDA64F,0xC2449444C6ABD352,0x9B30535CD81823B5,0x05FAA5A4FC31E419,0x1988F99739F5662D,0xBD2BAB1A1922BBAA,0x1927F40852419415,0xEC3649A9AE0A3C66,0x11D9D78A76B65905,0x24F9514A1F5E7796,0x7A25B74681F7BF3B,0xA14FEF937B2AEFF0,0x86F9B9829D894414,0x7AA06D1AE9A5D546,0xE36CA2676A6170AC,0x9D7B7FB9E01D7358,0xD5A6C80CBBF9A7CD,0x864C781B31449EC9,0x3A6085936DCEA0C9,0x8974661FC56D5C77,0x4642ADCC5625FBD1,0x6FACF21E41454635,0x4510E8B6687C064F,0xBA8BE4227A4E82E9,0x2B8BDAC6BA4D23DB,0x39BFA5F5D1C62683,0x2080FD09DDDFE6C1,0x6D0636E6784DFD91,0xB3239E1A5722676B,0xC4025E50D9EE0E2B,0x0244FF7CE318D69F,0xFB32EA29651FD1AF,0x0CD21439492C531E,0x01F1B108FC6FC765,0xEDC3C712664BC49A,0xC49296A5CA888535,0xEBD65449CE84C63A,0xA25B5DF58130E264,0x42C6B942518A4542,0x2C1ACE717FB16D16,0xFABAA6D83B21D1A5,0x4192AB8A95A2C0E9,0x86671D9E23EC4E9C,0x18B3183056EBC3A6,0x294C7AE000AFD679,0x3624335A8D0F455F,0x97F447F1B9293BDC,0xF20BB7B028DAD4BA,0xD055FB11B056DCE6,0x9C269986658DE580,0xAC4ABB4CB2D86B99,0x1FE75D766E46DB24,0x05D45B54E50654AA,0xB5DB47F3E7888CC5,0xE8AA27D8F1C7FD49,0xF32CF76C62589FF9,0x89C5E3E9342B8368,0x564B7280A30CD2A5,0xF6EEF2A58BEB30E4,0xB4517BB69184623F,0xED5A10572001B02A,0x649DE94FCA5FAB24,0x807D4C703AE09E41,0x5F5A6E7ED570E32D,0x739B8D953EF4B4C6,0x15C9B3E79920BF7D,0x64E9E90D73AC0DEC,0x0405B0AC5B05D136,0x1C02292F24E55CE1,0xD03EB3AF60EB1718,0x3949E45CFE0B5CF7,0xB7C14E155C0C8A2B,0x5AE440CCB4585DB9,0x413DFB1CDB0D8833,0xB36098A4A13D9416,0xBB4DB566AA87E5F3,0xA6C0A6CBACAE2AB5,0xE62695DCF15EB9A8,0x85D97B0D930021C7,0x0952D66A6F9B7A81,0x44259DC766F81000,0x0260E055C17BC2FF,0x810E358AA7FCC261,0xA80EBE3CF9EEB1B3,0xCDD6180BB9C0329A,0x0E1A1F6A20BC83A0,0x8472D3656530DFA2,0x472261560AC92DD8,0xA17A8F028E2E5AD3,0x488E5E20D04B3A82,0x208FDD0BF9536C3F,0x51679FEC4F916CF9,0x2BCBF09A11BA07F6,0x8647282451802AFC,0xE5B8530C5BB5D5CC,0xBC8A6CE1DDE22F29,0xDC6E189F13F32028,0xC2F521A86CBA393E,0xE355E19CAD1F7FF5,0x053FC8AFCC709F00,0x5820915F5818E2E4,0xAC06CFC75D15329D,0x20AB5F97872C7FF7,0xE931ACCB20ABF6F5,0x43D53B8929AE1458,0x5A390391D55767A4,0xDAB74F19562D66CF,0xD39F019FE7994196,0xCB0242F08028EBB4,0xD1264CF4FC72B40F,0x9BCBEC315B3A621D,0xDB737B9245D41DA4,0xE7DADDE10C07DEC1,0x6DCA1D02B082846C,0x1783E0A4BF09EA0A,0xC98A58117AE37716,0x38D2B034D3A8EFEC,0xEEE6F4CABAF0E202,0x1EAEBAE1A12A80DE,0x5FE0652734520183,0x9926B4F730455566,0xAAD46F30B7E49E8C,0x2279EECAD3FEB741,0x8D8937E77F0D2B1E,0xEFE671CC12BC7BE2,0x2328C239BFC753C5,0x1FE8216BD90249EE,0x2A1A282B787F5D83,0x9A7D173270BCCE4D,0x7815D44F047286E6,0x1F79290FB668AA6D,0x778D315FCFB98CDE,0x9D37181549214EAE,0xFB68139C1ACE5C8D,0x4687E9FE67F8492F,0x7ABF051EA2F04AFD,0xBC29ACD47451C112,0xBA9BC078BF7E9CF3,0xE783968ED85FEE0A,0x6B0127AFE2297971,0x13858F99D3CDC5E7,0x1099EA87CD16DAC7,0xFC07FB375C6188FF,0x1F740BEF1DF309E4,0x637B6F1FAA2F3806,0x47C0565E02255D8E,0x4D2A8AE2F3E81185,0x0880D5B2604868D9,0xE527119AF74FC762,0x4B0AA8AD7D2A1B7C,0xB552058C2FAED989,0x233A5F7DDD1827BB,0x0DC917E6DC4DB4EF,0x887DAAD20CEFB444,0xA8E05CF97E51A3B9,0x880E8BF5D089EB1A,0x2A2F8F45C811449F,0x45EE3525C228538A,0xD275873D560A802B,0xF619D95001832B4F,0x003EA857D7D296BC,0x47317E97CF5377EB,0x9B37843482CEF25D,0x8D613B4AC61A5198,0x6FEBD7E37D849264,0x1E1D815005FAE32E,0x818D07423B3138D7,0x199A7EC4AE3175BA,0xECEBC1F8AF7464D4,0xDF4C441651368928,0x0416C3B18D68BA85,0x642B84FE337B2C44,0x132F19C6176DF87A,0x7A72EF6C1512AF70,0x8336BCCA763B7C77,0x9E7A4BEEB3109755,0xC953EAE2596221A7,0xC96080129CA77CD1,0x2DB2741378D7F0BE,0x13FB6D10A5D7B92B,0x83F5E4188BBADDB1,0x115A1CD0587A2CB3,0xB169A1BE5A96B758,0xD2A98AD1A047E124,0x36DE535C5C673BF3,0x37E648365382A7DA,0x15AEA27CAEE2718E,0x01C40C055A85CC77,0x7844A55A6A1102F8,0x79F9012D8E907749,0x457552DD54B139BE,0xF8F5B6B398F77F7C,0x478742070C9B4E0B,0x1DD9E9B52D79ED19,0x6EA7BE3293C21A64,0xACFC3DFF1B1A9669,0xD35930FFD24B5A14,0xBDA082091FE1622E,0x12F1DC82A098B279,0xD1D33A568F43D46B,0x0785ED3E2A8F8F5D,0xDD6B790D8B0BAB08,0x3828EA82C8FD773C,0x8D7ED42961E01777,0x2B5036B16049068C,0x3CA0B15D1C9E5DA9,0x94BCD6BB0C840D57,0xDD7F55BB1645F843,0x606495DCB4BA877F,0xAC45B33A21E54F98,0x71700AFC6ED30D77,0x822D58A71E2AB1D0,0x0830E8C8857EF974,0x48AD3D92CC09116F,0xF82EDED9B11DC031,0xA7FD194C8001C718,0x30492EF58E1AA45E,0xB2FE0AD6F046679E,0xD0FD0B8194C4CA0F,0x5C50992DD88A024C,0x91C2B5C945F91B2F,0x2E80DF93B0917655,0x2A42D8D346825BA6,0x2C97ECFFFBBEF016,0xFE4B8F4C235C0FFD,0x0D59562C60EFCBCD,0xC07466D0DF7F6D47,0xAB98EC3E2BD0DEA4,0x305A14452E98CDB3,0x0BFEFAF663BD4F1F,0xDC410A9003F36F85,0xE135F992669F0E56,0x35D18A24F21704D0,0x4203CDA985EE7369,0x65C0454BFA4D50A5,0xC98DE5FD29E9AEB7,0xD18EC92BFEC40BEA,0x0987049B42681662,0x5A973E45EE1D024C,0x19A68313B1CBA422,0xA62FD408C58A2D89,0x6919325D4E21C194,0x6FD04F6AB3782DDC,0xDF0A7588F12CBB87,0x5DB5DC36C4570EB0,0x55237A446BA49D10,0x0A056BD93D00D9D6,0x1863DB828E554126,0x237082818FBB39A2,0x0CF02EC0049DF7B2,0x491D769161AA9D6A,0x1EEEE3796B195481,0x119B874397C13A25,0x270024FB83827214,0x9AB4B4DD04D78DB7,0x2457E260BC78B961,0x1F1BC698979BBE1B,0x67FF93DCCB3EBE20,0x4D914CD2835866E1,0xF429BF3C0A8A1A5E,0x5843BE05CA4141E6,0x9C0D11EE0FE1D1DC,0x91999C77BD5B3244,0x3A521CDA182D4562,0x9D71D37B7CFCF426,0x78E0C19B3C1BAB3D,0x4E12D49B6D7F6508,0x355A82819489A1A7,0x0CFF3C5F6DDA8A87,0x1759495AEC42680C,0xCEABDD45F0750F4E,0xA9F73E351638C515,0x339D8BC57B7BFD80,0xEC09F54F9CFE87D2,0x0D1E6E479DF0E32D,0x3BDBF353D11D6138,0xE1A25A3FC1F6574F,0xB8BBBED96DEC4585,0x916C440107554F34,0x948F1F6C28911881,0x00B9C78381BF56C3,0xE1FD2B0C12962B32,0x8521A3055C0576B4,0xCCF69F2D29A423FC,0x2B1AC93FC0887788,0x4F69148A65777444,0x59C7192530C7CBCB,0xCED6337BDC1B8E47,0xD2AAFA62AE927BD1,0x3EA3DA954104DF90,0x31406C2C22C72617,0xDA074F40B173BE97,0xCB032AEA18FD8484,0x92CA8B6E1F99498E,0x999B1A43EBA29EC8,0x4C987356441F6A5F,0xAECAD058BE01629D,0x505E9692C96A0B1F,0xC1A9A72D0DE126A9,0xE586A07C9F931660,0xDC9EF6787BB4D5EA,0x210C90FCE620EDCB,0xC3257504EC9A3109,0x9BC593BCC73EA5AA,0x8F80B6AE0B395ACC,0x6CE8A3DF81D044DB,0x0E9C1C1F675A7576,0xABD61C8B1BBBFFD3,0xCD1CE4FCDFDABAAB,0x770CB2E5D714FB15,0x9DF37C9F1A740FE3,0xCABDAD96B5E25663,0xA0DFC5792A172422,0x5718BA1C81F36992,0xA2167184A960C24F,0x64B0425B1E3E2168,0x9B5B1F0222F86FBA,0x53E0F5629E41F4E7,0x15E984675177503C,0x26D9C645E82E7D8F,0xC46E66164155C654,0x6856DA22477C1789,0x33D58298A0B1B53C,0xAE6B785500CEF880,0xE29A4D0523F6A406,0x4DBD74EF85696D07,0xC8D5AE3FE72128BD,0x2D81CEC211E0269A,0x0769F0190793FA68,0xD82F03E39C9387FB,0xE16B93139DBAC4DA,0xE48CD129BAC11515,0x97132227773CDCEF,0xA3398A10789867BD,0x9013B3A51DA397BB,0x91D1DDF996185D44,0x656A6B4D8FC72CE1,0xB90220FE8BE6FE10,0xEB1D8B952D06223F,0x06FB3719291AF272,0x162F302A9FE2CB19,0xF9AA3A83047FE46F,0x9E368AFB4AAB7EAC,0xF761FF75B1D297F4,0x4D019B6105615C2F,0x0E05C5EF466149D7,0xB28844CAE0BFD692,0x7F796E08D1F632AE,0x11025CCD943FD2BE,0x4AEB154C163B478C,0xF46E7C8E147AF4EB,0x83B13C4B8D4B3402,0xBCCDBCBDC7B61963,0x02C07754582D23FA,0xD2821A86CEFF83A3,0x7B632054E4537DD1,0xEE9CA7803E1F3BBA,0x7B5899E1F10E403C,0x011F12E66CA0A343,0xF910E79DA8300ED7,0x9B19CA086218C4C2,0xB43CEAD92B83D105,0xA02D3883EAE5C1C0,0x01FB944CB6E17B3D,0x4C0E1A1533739263,0xE98D8DCCCC806619,0xB44DBF7C1C1C2240,0xBD48B9BF64055FB7,0x97866557307106D8,0xA1A716CDC65701F6,0xD62D960334038A4B,0x751CDB44891B9B93,0x82E6D923A25055E0,0xD2E93B55D246D753,0xDE6D7481923A4B60,0x4F8916EE47B7467B,0x63192BF14A8B9D91,0xDD36F45EFA611A71,0x81A47E7A72EAD7B7,0xA2EF14D524838FCE,0xA93B777E16DA9FAF,0xBC6AE2D62AC24CB2,0x3615189A3DAC1474,0x0A4B482B5F31E23C,0x9E19DAE58628CF1C,0xA87071736EB66419,0xA2E988828BF57AF9,0x905EA7DCB219D821,0xC1631EF40733CD6F,0x6CA8687019AA199B,0xD0E8E87EBC11087F,0x37721D011B7F0AA1,0xF92DB87205C2A66A,0x272F6716F66AD79E,0x60C3A22C20E13EDE,0x681B850161527F3D,0xECC4EBC4E04B5A93,0xE362C7DA20D47FE0,0x284750BD376C5C4E,0xE0EDAA3A83517C20,0x30F9D7769845291C,0xC93EF8AE3B85F97E,0x24FEF430D4FACFB5,0xD386B1C232E25CC5,0x29223793FD2255A0,0x33337156DC608BE0,0x6CA171B79C5C3C97,0x10CAFD5ACC5A0213,0xBA010478B5CA09F8,0x7721E554C18D7483,0xC011884121CD6978,0xADCA765AE94782E9,0x5A0C14A3569E3E1A,0x2ACF1E9E1F816FBF,0x3669D8F2244886A5,0x71801FDC97B3B585,0x59B2C6786F7A6B1B,0x35EF0EDC01B51F68,0x65EBC9C2304E9C2E,0xF1F7CDC760D34BC9,0xAB583386A9FCC5F6,0x4DE34FF0D4B34D4C,0xE7D68C81E2F7A1F4,0xECE01AC8D9E96C36,0xE91F486021CA5108,0x69D272BD797B5C99,0x1C1C93FD2FF06955,0xEE32A3D6848D81E5,0xA8E7B5C86F0E0566,0x631DEC8515F1D6BD,0x9A08613D1CBA0366,0xE09C479F64781121,0x7FDABE683AB5E79C,0x810EBA4D17B84758,0xA332B2F0E1625949,0xC68553E1EE963992,0x98D3EB45116508F7,0x7141DBEBD14FAC1D,0x375288ED97EF3F9B,0xF1AB8FE5D80BBDA7,0x168BA57A078D9794,0x8DD988BB3642C3F8,0xE28D848840A9950E,0xE74FA9E73540DB1A,0x6F747F636C92FEAA,0x147B54899A7C8D58,0xA19F86AB02EB77CB,0x7F6BA9ABCF0B552A,0x8A645F1CDD5B53BC,0x6277238C11196A00,0xFB0F6C37D47BDD69,0xAA1F7C8950D57B7D,0x55505AA7A341D494,0x4F883554E230D3AC,0x8A62EE4AD3462D3D,0x17D366F911C56EA1,0x0F2C0BB6226FB758,0x9FDBECE6B35C9D85,0xC656CD0BEA4B88EF,0x03C2F5707860B33C,0x6E89EA59999C4F33,0xCCD385146369C12F,0x46A7814AFE39FE53,0x0661F76B58ADC342,0xC5D32B9EC1A485E5,0x59BACC04A48DE45C,0xE4C8D61AA1A6C176,0x12E6A38BC4E64605,0x0A583A20D2842498,0x6A8447B230601836,0x66C088B81A7EF461,0x7B759FA9367B43B8,0x7C292194C1C36F6C,0x638FE44BCDDA5C9F,0x5AAA8CFB9109192A,0xA764CC8FB4A1845D,0xF74C08BEF97E4BF2,0x0589031BACACD647,0xBD6E83A825C3B507,0x0EE8B53C64CF8195,0xA4029F391CD6AA97,0xC7B6D4456C9B1842,0x8436C5376DF02F65,0xCA336DC481A4EB11,0x1ED35901DD71220E,0xC317CEBD3FF60B96,0x9E9188EF6A7DBC9F,0x8577225921E3A1D2,0x043A5C2B63F48BEF,0x24CF7AC0B3FEA778,0xB30288752E95B6F8,0xCA476BF1E1678511,0xF8D22BE553305680,0xF181B4FD42AF8B88,0x43012A8514854008,0x1D6166FDBC7BCFA4,0xB1865F76C5E43336,0xA0A3B6F20FC9D6F1,0x85A574A2F7542A8B,0xB556A76C97E98861,0xC20355E5A6D3343C,0x1FFA74122480A7C7,0xBA263B11BDC23B0E,0x77267F08BEA7B4D4,0x734A7333CF9F59B7,0x82911E5B0CF48571,0x324699AE90A3ADEC,0x37430BCCAB01967E,0xEF666C1854E5CA17,0xC5B0982D2E6B686B,0x157AE886F964318C,0xC04CEF97350BFC21,0x3EBD601617EC6D72,0x0A7827DD88C2F3F1,0x257D5D41741D94D3,0x880DDE735C680B48,0x88297A66A7B27837,0xD2CAB73D366EE0CD,0xE2C6255281662332,0x8F005A0A636CE428,0xA0A90042F8AE814F,0xA3D8DF731F34B0AA,0x4AEC5984201AE689,0x227678504673317B,0x02AE10093D1ECC4A,0xAF9822C0772EF103,0xAA05160F4D6F9CDD,0xDBC4A518D7959512,0x2455322F556AEAE2,0x6F4765433F96BC06,0x5D189CF425842C0E,0x4D96659FE91839F6,0x0D3C69C15D4EF474,0x9C82776D3E53A6B4,0xF19251EE958924F0,0x368E47D25A3B4D30,0x9B4F38309AE6125F,0x668428142AC4C603,0x6DAF18A3DAF321C3,0xE0A0D4A2E7F05158,0x73503B697F61A8F8,0x086A9814FEF40D47,0x4F1959C619539549,0x44A0FD4550F96D4B,0x0D6042B2594140FE,0x7A3406A32E797E5B,0xCC4ADE0BE5C1CCBC,0xDDB9A062BF612BCE,0xD52C610E30432FCD,0x0445A2226404B4C1,0x548D8F04EB5C7B0A,0xE183BD3AAEF55822,0xF6A7AD96A2C9FEE2,0xA83FD34581039D5E,0x80807AE8A3DC6DC6,0x13982F5511761D68,0x7291AB2813B9C490,0xBE1F1D84B73907D1,0xA1CDE2F54ABE73EA,0xF6838CFAC0388169,0x9A987DFF3AFA66AC,0xF942D94459B9AD4B,0x19E8EEEA0ED2C624,0x270E889CE56981F8,0x5DEE9E387A211152,0xE6F8A309D52CA0BA,0x6C32F7215FDB8C32,0x1088D80A27E23155,0x052027626D5E0693,0x0A03CB598ED4253F,0x976D4A2F2FAB15D2,0x7BD4212C703E41E9,0x35F339D0A21E821C,0x64D18729886CE4FF,0x53681BFD8C4D8F62,0x4778AAAB2E607C3F,0xCBFC67A99DB617ED,0xA238BBD9D55C4952,0xC842496A8D21F54D,0x41FD115750A2CD4B,0x109CD514B5C82419,0x543D9FF1D4ED64EA,0xA5C7E9EAB5323C82,0x3B63AA1375FD7E3D,0xF3B4AE7CC5C80251,0xB098076F9F6FF574,0x3D032E3966432F98,0x8CE08D085FF6DB55,0x6F585528DA41DFFE,0x214CB9A2547C7C08,0xD31A663A37A145E5,0xB3AAF91312655657,0x3E82C760D813FBC0,0x6216D33DFF05FE14,0xCF199E7D5B9E1171,0xD37933D4C093F689,0xD6261C04A1E95C0B,0x121C8F7E9E773D37,0x5EE820DEFD56B992,0xB32C555A214387CD,0xAD6A3F01DBF5282C,0xE5484A346791822E,0xE63A47298D2E2A2A,0xE6E9E64233E32A4E,0x4EC0A50BEF6C41D4,0x2D395F5F67A13C59,0xAABFD17C9064D6D0,0x52292E4E53E3863A,0x666D77CCBFEEEC76,0x475BCF1DF8913EE5,0x07FF33D3ACD8BBE4,0x13CC00D6343F6119,0x9F34EE0A868D3936,0x014E455AF3D54B7B,0x6234191047C58AED,0x15B1C44C5C59DD45,0xD515CA18E0899D48,0xE1F4FB981277E94D,0x479E8541985082F3,0x6D04E83CBED49D40,0xD976BAA9244B6C08,0xC4A9901C783EB400,0xA4CAEF8D6096706F,0x9DEBFC58BB6D3737,0xAF749614B8ED0112,0x5E9503D6ADCEFE4E,0xDC0264B792CFE36B,0x13285FEF961B2439,0x1EA6C56F519BDBCE,0x822CD7C274AB762A,0x6DF89FAD21CFAC19,0xAB50FA14C3AC1238,0x33E63DA08117D750,0xCED57A0DB12DA9CD,0x9E359054142CA0D5,0xA6A81DF7F7C27338,0xEEDE96F6655B2B0A,0xD5421EEE8DA2BAA2,0xF8FE4C0042A12424,0xE81F85AB4DC7679B,0x21D5762A2A5C0CD8,0x0BEE5CDDD6FA6C88,0xE0975398358FFF04,0xE2B87E47D2147F62,0x866E905443241001,0x26CE9F63C4816E5B,0x242FF5B219A98582,0x73D5A5C34F517F61,0xE076FA164BA16000,0xCE93EC8404E736E4,0x904FC259D40B87AF,0xFE4DA03578E33BC4,0x422679B01B5C8601,0xA5582C00D19A0EB9,0xB9D331714E0B88E5,0xEE9947E25DE28FEE,0xFD788AABA88BC1F7,0x2F9D152A51791F43,0xFFA7318C7DE6C1F3,0x6956796B34414791,0x1229B9EAAE320326,0xC59E0161081710E1,0x0FD81FA09C48C89D,0x2CD82D0145D1E527,0x598B2F8E96FEF24B,0xFA893AEB723359D2,0x1497C0FDC77AC2BF,0x526B4C2BFEB77455,0xAB688C507B7584BB,0x2C28C88445BF164E,0xC744163DD12D1E1F,0xB7C4613DB03EF192,0x09F231DE715E13E1,0x127F08DC42656B5C,0xCBAD7B54AF9526C1,0x2F67A27A77737583,0xDAC675984603B2D2,0xAC194CA0330309EA,0x1EF58E0E2D80D7A5,0x8EA7A8E677D4C444,0x7871729892A64E93,0xA15B66966B13DBBD,0xE5AA71D0C0A2B4CB,0x658D6E3BD22B70E8,0x3DBAD741491A5D16,0x88BED89C354F5275,0x0EE1D095D2FABEBF,0xBA07EFC612BCD3B7,0xEDCE9E72C445B1AD,0xD21FDF5C955CDEDF,0x45BC528A57F8FD47,0x46209C14D3D47610,0xCA9D10EE2B338A87,0x916BD548D1048239,0x8452AD863BA78B4F,0xF46CE20043B477A8,0x8004132AEDEC624D,0x412EC9675488D4F9,0xCF56DE200F4F2880,0xFA8E5C4286B5B725,0xAD094747B7266B02,0x7684D5FFCAD9ABF9,0x4E6B64BDC52E4981,0xDA2CC5BA23DF9094,0xD989D684FC32BDC2,0xF34C3A78021143AB,0x8C4402025FDB1CC6,0x3428544F8D077F30,0x6B2AE9B1C7EB160D,0xCCBAF5B449CAD46A,0x2E5A1E8866808ECC,0x9200A64D8782F2E2,0x00890581651FAD00,0xD9B99C5A9EF56AC9,0x185DF172584E2755,0x142AF4C2D994FFCD,0xC964783FC27968A8,0x464414194608D8D7,0x0AA4EAF5385047A4,0x40CEBE41470028B7,0x361D357A26093103,0x67A880C4F90C137D,0x26B77FD8A61CECCF,0x58F1A46C239200A9,0x7F5417EC86AB6CB4,0xCF0B5C042FABFE02,0xB1C95112E0B18AA2,0xDC6C8BA857771F94,0xE3C0B473BB53B292,0xA702FA9ECF399B3B,0x4AA6712B3D0D38B5,0x6775FC53CA98714A,0xEB491AA0D114248F,0x231AB70766328045,0xED825E149DF76C2E,0xC41018619451BD0F,0x45C2ED27E6022EDE,0x3F898C4715072760,0xA2FA08359E6AD706,0xCC8CCF63019EF85D,0x19AA38BF6333D137,0x4E0DDFB96DC5F623,0xA31744AB17EBCE7E,0x83A6B7A4796BEBDD,0x7FFAD31BC5EAD14D,0xABA90D1E95EE6ACD,0x67B124369EF14B97,0xAC64DCC81A84C335,0x7A4709331450CC60,0xD645106D8097F986,0x944462C444A18951,0xA26F41EBA044D085,0x4F9DCD597CB87F35,0x11F71AE96BCF01B5,0x229A63B5C7AFA813,0x301361A31B6242E1,0x9359AF62926B08AB,0xCE714C259BEC7A14,0xB0E0CF0F452F594A,0x2FAF6D7038426E3C,0xE946E7C6CEC263FC,0x140259A780553AAC,0x088EEB8ACDF14193,0x78B9115FD18F7385,0x210F7E556BF835EA,0x8B5DDE2B91452BC9,0xDD4DE5F0DEC14A19,0xB5EB8B9A73757751,0x5842F6796F720E04,0x786689FA4C213622,0x18C17535EF22BCD0,0x0EB9E94F830E8BE5,0x05AFCA588167EFB6,0x3C47906E7BF036FA,0x9C1F0FC9703A66A7,0x223F5792E8BFC259,0xE0FF67171A939939,0x73CBA6C5091E18D0,0x1039FC11580844DC,0xCC32256E3113F47B,0xBB3EC88EC8722E83,0x30C6995C16083A86,0x3E78A1750D1D867C,0x8B63437FFEABF28A,0x5F4011912378148D,0x820901F91D4B7CB6,0xDF5E2EDEFD019F45,0x9BB3BC0EAECB7FA9,0x133FC7EC72E75D26,0xDAA64BB6954960FA,0x381F0D321F47C13F,0x7F4D07C9BD0692A7,0x13C1A3FC44F2C341,0xFA0F87F5D7F457D2,0x6BEA99191229CA31,0xAEF7D580C664F6E3,0x4B76363DE109AD70,0x05CCCBC475C5A43E,0xB792D81F197C6AB9,0x07D770D698829F96,0x6E2C2DB21DEF2310,0x35FA4D09D7AC7EF5,0x84636A85E87AC6BC,0xD94EDCF62953B1F0,0x469C635A84A95018,0x0D9283AE8627CD5B,0x149BC54580A470BC,0x9F3F6E15197CF1A2,0xD63C6CE3E81278E6,0xFFE6F864A24B38C4,0x6BE1660ADBFC291B,0xEEC3B1C21FC0A2F4,0xE08A785A5350EDD9,0x559B833FA81B556C,0x8E5534FAF6561682,0x47EBCBA4289782B4,0x6EE7B431823DAD51,0x03A04969BF6A2683,0x75E337A7B401F38B,0x1E19D390D8287E10,0x02A28DD4B477AF64,0x5D8B3B4A17A9442E,0xD1C229141B124E89,0x0AD7B0A8B997A274,0xAFB8BF91F6F830F1,0xC3AC03F15FF6FF21,0xFA00E184DCB19C74,0xC72E175DFD2DBACD,0x75CDDFD1620C371E,0xBD86C8E7F31C3923,0x04F26019A75DAD1E,0x80B41F0FA3DE321A,0x0D1431B055A81EE0,0x3EDC168C861E0F02,0xABA4B3AB989DE4CB,0x8BEF8FB8BD639408,0xB743402FE1D8C885,0x4B4235F1BFC4EA4B,0xE03E4C688A3F2801,0x00650E2341BC2A35,0x1F880087050F1B1E,0x8246F751705BE6BB,0x0B13173E26422BC3,0x31FD2AEF078BD9E5,0xE1315C69700DC4B5,0x218124CA34480E61,0xCE515B3AA4C3A333,0x2F8356FA9A8F8746,0x8144FF8059FA0C99,0x665EA2409FCC776B,0xED2BE22C65C7BFB7,0xAF61ECEA610486B0,0xC88747A6C9B08491,0x4A8AE25D2FAEFC78,0x36481DA508534AD3,0x3DB3F44C19A2B3B6,0x382DC1682BCD180F,0x1326A95980D6DC7A,0xBE780D82BCE800E4,0xF950BDAA2D6D683B,0xF53A5562A6662BD9,0x33FCA71232F4F367,0x7184E5B329013998,0x5E246670D0757BFA,0x4F25DF071D26D250,0xC2F57B072332F333,0x6307F7BB6901C2FB,0x576AC584585813DD,0x445803036D367500,0xE63E7F7745140FDA,0x78E9B63998E9573B,0xAC83364518A8C123,0xABE105BA7D2F0EF3,0xAB7C2AB06B8BD8E5,0xA0885F6983D6EB7A,0xD896EBC74654AE46,0x4D98BBE3C0D67A53,0xE37A887A69041B92,0x7B22706B3DCA6C29,0x9DC4F85C78AC12D8,0x6A1C6E103363E69B,0x013557611971B9B6,0x8B8BCE4402C43EC6,0xFE949A191077DA79,0x7D74C0CE345ECE05,0xC50ABE4553CC9B62,0xADC7B6BD14DAB0F7,0x972A6B1660DBD27B,0xB68DCB0A1B6E5502,0x4462BED2FC83647B,0xE6B5384129F8CE92,0x0CCFD4F62214BA47,0xC24536E86F48FB9C,0xD88F8076E09128AE,0xB399F080237C681B,0xBE6580DF1D6BA6F5,0x5793B1CC8C752FFF,0x2C766CAEF17B62AF,0x9B97E2FBB61D56FC,0x04AD140A6AF3F889,0x180285B38FA3B4BF,0xFA239DDA37D88F0A,0x6623D9D337B15600,0x0C6154C17DBDA211,0x64FF112A9B3FA75F,0x4ED17DDCFED94C82,0x348C9D3C48A5AC99,0x5550DA61334F8005,0xDC201E1BD610B6F1,0xB83EE4F40353C6DA,0xBF579AE58EDD34B1,0xDBAE0057770E7AC2,0x40F73C9E59467888,0x831608B5ED55CF32,0x9C2375C1066A13A2,0x26902BB4D6EECE3F,0xFE4AD1C161C6D97A,0x2898EF7D98056F4C,0xCD7497E6A10599C3,0x67AC891453F64508,0xD20D65E1BE0771BD,0x9AA20FDD103D4AF1,0x586B8E77C8D4891D,0x6447E007AFC0860E,0xC84A322E2EBE34DB,0xE89885E74A5E203F,0x6F6985678AD2AA62,0xB8D6E0567C67166B,0x7908D2D10C152AFD,0x511A5A39F6488068,0x1BD81470B57C6F63,0x0AA3B3E5B994E332,0xC72114DA6021E0DB,0x5CE30997B7B2157F,0x9B52FB99A242FA29,0x308BFA24F21B9C10,0x6564738709C81E03,0xDA295869BAFA49A8,0x92CE3F3D74B474DD,0xACED541EFEF70E7D,0x839EA7D17DCE4EEC,0xA1F441EB78EEDA73,0x9595EAB647A4EAC9,0xB470EF26707D0A14,0xCC75BE905E449437,0xE6283A3D4E7A782E,0x47EC49E23C0F0F11,0xB9402C15430F2401,0x2FD4562798C4BC6D,0xBC98C11A4B8294B7,0xFEE76CBA13432A67,0xF165588595A53929,0x30ADC2A16C7F6445,0x889930FDCC3E1986,0x71A5F23551A0AE2F,0x19D1FDB51E3B463C,0xE18611CA59E08D34,0xE97D491026AC1C1A,0xCE09F25227422BF1,0xF0FBA6DB90DE4BA3,0xB63DEAB16442E9C1,0x6EA2261DF8573E7D,0x12B73C498379B95A,0x11BCB33C0A6AC886,0x44142F0E2D90D2D6,0x1A93E32654B332C8,0x7FDA13003C474802,0x76A02C27C095EFD7,0x89B6D2F45D15C27E,0x790347148553B9CC,0x6D4C1B773C37727A,0x9343142FD0CE75CD,0x96179869F2C4685D,0x57172B5529DEBDF6,0xCC093035054AF999,0x8AB01A230F7A6D2B,0x11EDFF4C3F7D28CB,0xF944A1A5582C8980,0x7E480ACB6F23034A,0x0D5771DC0FC15DA1,0x6A4B94672238E7FB,0x1F39528C7FF7C028,0xC51CC07104ABCE7C,0xDE1217E06B388578,0xB46AFFA2D1CEF93F,0xCA589178AF523905,0x537791F3A8E8F62E,0x80A4355CCA067AAB,0x3E967B1A87376AE7,0xE266D806D72D344B,0xF3C0EFCAA4091B6F,0xF370FCE84BCD0E6D,0x8561F4431C3746DB,0x2DF13768F5343AC4,0x007E053B5402FDEE,0x4C77E655AFD52591,0x0DC33258F8FC6A96,0xF02EF0543BF2AD4A,0x4E40190EFE931A97,0x44E0B41B33498F9F,0x51580A6502DB39FB,0xED35E19CF4C4B35D,0x4A130A43E3F44EB6,0xE1AE77D87317A261,0x6965EA891B8B8BEB,0x0309390607F78A20,0xE59C33123F7F3FEA,0x41E58E71BB5E7FB4,0xDDBBA1D182B36CBC,0x6CDA53F4B4FD67E1,0xE45702443C952971,0x6AB0D1301223D2E7,0xF7A9D8E1C6C7EA05,0xABDFC872A7B05ADD,0x4ECBC6902B9DAE63,0xE868F157C074F0A1,0xED2AD03CA94625E1,0x349A9F5D13F0DBB4,0xF8055F09143CFA4C,0x1A803E77D5702248,0xC801A1BD1FB64389,0x259FC7F34E5BC3D1,0x15CF4661FFED3FE6,0x6921B29BD10160A3,0xCF58F4840956DE50,0x5B32E54D752E59EF,0xDD1719A9B07F6C76,0xDCB6CA019407D77A,0xAED17B33E48EBF6F,0x0E54FD637B8FF17D,0x6B7D95086EC1EA73,0xA6C72C3E5298D391,0xFD8E7A3DC61A16AA,0x038D76260319BA2F,0x69D59801E823055D,0x3ADFA3CCDD38BAF6,0xA05750A4B809F550,0xE5639DCFD309ED55,0xAF128CD376D0770A,0xAC4C880EE5648888,0xC6606FB7C680D9C4,0x414BC34B648836C7,0xF80C704957C8A3E8,0x510FA168FDC5208D,0x2214C274C62D7390,0xEB17A8E2AF84D066,0xE58F37B55311FC00,0x184A0EFC7ABA98F2,0xA2551BD86FCD13C1,0x5C8E6C5D1FC9936C,0x545A38542D611B58,0xB59A3DD0572952A5,0x5FE550AD276946D3,0x31A7F436004C9758,0xC426FC7EC9DB4F83,0x8F13667803B2B1BC,0x60F1FE2496340EC1,0x1C7BA1382527774F,0x2DF13DD8B51897EE,0x901D742B720D10B8,0x826E7D8ABB29D5DF,0x2A7985B1F013DC76,0x0366227D89A461B5,0xF2B933958265A52E,0x67B713DBDA46A369,0x338CFBEF7147EC11,0x46C17EC668BD903C,0x2CC9B1E687F98CB1,0x48090304A93AE8D0,0x038C39E106135F3E,0x194ADFDC55EE502E,0xFC0BC34C50F167EE,0x19B6F3A302F39460,0xEB275B47F1EE0B20,0xC0D5A7F7ECCC9013,0x2A277A5728D659BF,0x729DAC69ADEC2E1E,0x279C866F9E68B053,0xF7FA4214B0B15524,0x84480F9CD554BA04,0x9B90FC8C2D8CC03E,0xAAF410BFA0B41AC0,0x35C87810F0382C5F,0xFDBEDCDCE35B8030,0x702525C454CA749E,0xDE6D1CF9BA0EE181,0xD4B4EB7D46DC9BD5,0x66A93C8808B17075,0x9819E2ED8B6F7BFA,0x22724FE9AA96B875,0xF6876286E341DE1C,0x2BA7A176511F898E,0x673C6ACC0A24D83B,0x6837AFDB3A539E62,0xE59EB586FCC854D3,0xECD2873BA96E0BB9,0x6F42BCEFF204DCAC,0x7B12683EF255C88B,0xEF771069CCC6D39D,0xD606B26DD0950502,0xCA21932F5D89DE27,0xD7BC4F7E795220CA,0x293CD463304F5AFE,0xF5AE49948BE35B99,0xD48661DEF154CD03,0x8BA476836EA1125B,0x5FA1478EA7D9046C,0xA6AFAC581A32C370,0xC772F4575E8C6416,0xDB5E301A2FD45301,0xFA0B0F715DE22C4A,0xD23C04D0D22CA321,0xC2D8BD7ED89A07AB,0x8F121302D8EB4663,0xCF7BD3DC7BED4CBD,0x16C11CAE6402AED1,0x1E1D1C52E1CF2384,0x909296B3DC98A151,0xEE471527FFE9DA57,0x946C86F2BFA66CC7,0xFA3A85ABC2A82745,0x230519F8FF0EC100,0xBCA323FEEA9C6464,0xB8E1BD2C24D78135,0xEE1A7420AD18BB6C,0xC49C7D7D0CFF4900,0xB91A9B7ADAB3BC9A,0x0E7AF0AF44BC0908,0x2CBB477199A7FA3C,0x8C3E5AA22EC00611,0xEB9153EA5A601045,0x289DF23165922A5B,0xEC28737D89CBD8CB,0x98214C72594D4BC9,0xEBDD78C0438A56D1,0x6A553F7CED1404B9,0xCB412F7170334250,0x1990247CF04B7774,0x1112CBA0520CEC23,0x863DCA62E1C49B2F,0x1265C125190AEA3F,0x7A07ECCD21E27B49,0xA7A9BEA7686CDCEF,0x9166A21E60CB932C,0x5C0EC9A1F1BDC664,0x6C9CE60C3D476D1A,0xDE3119757EF4B81B,0x21213EE3131F7579,0x8DDEDF8A0086BC05,0xDA90DD847AB8CAD5,0x182B8AA31A10B576,0x7D77E508D24919F4,0x7D43A3ADAF61A7A6,0x9A34EA0188F0F575,0xB3E44FEAA8488C36,0x15C62D3014850FF6,0xAAD61F76337B7ECF,0x02F27100A14562D0,0xF1B2B79E86A80CC3,0x9CA48D60B690FBCB,0x533DF584A5082598,0xE827CA9E36F86EED,0xDCD84B3B84691253,0xC91B13B9DC56004F,0x96AFEAEF25A94577,0xE72132CEA6E47EDA,0x747C98B03B4055DC,0x866F6EECDA0F422B,0x3E4023EA35677F4E,0x87E65687D8D80672,0xCC5E89022C3F787D,0x51FCF9D5CF355DAD,0xD733D5CBEB82FC0C,0xDBA3B9584FCF0E9B,0xC2D57568E356246E,0x1FDCCB1801EC6E73,0x2F09FACEC725B8CA,0x3D108F662869AC08,0xEB855089EA97ECA7,0x9F209FAE36D516FC,0xF17C75B58B97FECD,0xAF9A4A36DB735181,0xBFFE04C3CF87B139,0x202506EE9786AB50,0x2DC82F9494D71A39,0xFA2B59BDDE86CD98,0x23DA0E38BD82F984,0x1D540D01FDBAED20,0x1EC9BED1BC8A8D69,0xE04725EEA7E0E3C3,0xF6313831AF3E67AB,0x30E293434A96D5A6,0x9D346E240E028523,0xCDF2CAD2F1B2AF5C,0x52F5A3EE0DAF4265,0x168B24BDA843DEE6,0xFF65B6C6F43C006D,0xBFCB65A3CA88EF24,0x07AF99A1833940C0,0x2755EA0982693C4F,0x43D403D41A3FF3A5,0x24C0F1D128CCAED4,0x0755B90670534F79,0xC0D2803A4726B98F,0x16317765229B7FB4,0xB48B073DFDEFC83F,0x39DBBE522995B5F7,0xAA5AF8A9BA9006F6,0x4C5D26E59526698D,0xAD7C71AC7034DE0B,0xFEBB9E7A3D538840,0x33992608309DEA23,0xF347189E320A477F,0x969F34EC2D88EBFC,0x910EE27EB9BB1DAD,0x81E0BB3537973F7C,0x4BEF3813CF1BAAD0,0xD99D2070D158CEEA,0x280F3ECC951DE1CC,0x7F666E615388FED1,0x041F166E2E4A256E,0x51FAAE74CA8E21B9,0xD18974EFFEB72048,0x699230F6852B47BC,0x02DDD3BE1380AD0A,0x61A2C4E4F2FC95FD,0x1BB7A5428CBE9627,0xEA3DB6C1C5E3830F,0xE9A9CD0907235CA0,0x74B17B031D0B3E68,0xA8601008E5C6C949,0x48DCCEC4CFC99AA8,0x4EC169D1B6AD8B98,0x000D58245238B721,0x2DA4A3287AF08D65,0x4CE94DEC4A163836,0x5E94AC9F47006E4C,0x768E21C0F2EC6CCE,0x0F4292BB4F118604,0xEFEB8A5C2D7DD230,0xE87E5956F04ECEB9,0x928A2B838CFED727,0x10F5E4ED67D05882,0x3F8096C61563A249,0x68953CC96BDE5F39,0xAD9BE95EAF67DC0B,0x902E7549B1A862F2,0x39266E7E75DAF8C1,0x0D4E4EADB81CE506,0xBE30FE7C5BE80314,0xE7A0BB064AFB2EB7,0x3412FB154413BE66,0x5BB7EF45863BC67C,0x420DD16DA53A61C2,0x31937727AB9C8329,0x122C8E07EAC3362C,0x9BA99E61195085E0,0x22879A8367E35E98,0x42A9A55B6BA67E4E,0x239C499C7F3A120F,0x5E11FE50CADEBC9F,0x9E270EE86DD75E10,0xA4878DC462BA25B6,0x9582F5CDC7D3BC87,0xC554CB1E7E4E4883,0x8842D4F3F98A8A74,0xCC3BD38ECD765786,0xF52ABC0AC8190656,0x29AE0C86A6AF0D7C,0xFB10B101CFE2717C,0x733AB877FDCB3702,0xDCFA959E4874C54C,0x5523C879A7D93AA6,0x679B05C3495BDDEE,0x549E3071DC85513F,0xF04BAE35100EC46C,0x4BF7FF410F6C0C0E,0xA358AAE9F8CE2562,0x5DA00A82CD434028,0xFECA835D658A37BE,0x78E4E3E3FBF1DA4B,0x62E9609710236F60,0x62E31F39AC2F2AF9,0x724453019815C225,0x2277729A87947E35,0x11C430B56385B701,0x6880C136BE8551F0,0x3A09D93730B26E4A,0x5F2A21284558DF42,0xEDB228A1CA0C2D4A,0xCFFFFCFA91FF3127,0xD57CD39670AB9BBD,0xF04010F70BBAC4E6,0xC5B599E434B4F11B,0xC1527361014CCD51,0xCF532F70A4F4CFA4,0xC1FE6231B6D29A8E,0xE90FD850B124DF25,0xDEC91DDAC60AD9A6,0xC15BF97B588E428A,0xE6D014F242EC4B63,0x3C71B71462110857,0x423941322731DA56,0xCDAC45AEAAD0BD2D,0xD0F34B38F5CF5172,0x6CAF56049B804583,0xB0C13DB3E9203CF9,0xE927478328B923C5,0xDEBD2EC632C075E7,0x5DFF1DFB64B1C1A2,0xD3DE566757103374,0x29BDD169F869813D,0xB71CA2286F3F469D,0x2652CAD3D8C4B073,0x0AC3B67265D23C1D,0xC3AEFB4AC960804D,0x44B18A0571E121CD,0xE84607CD82D11EE4,0xABB37498A94A1E25,0x0B05DC57588DBB04,0x4D846069116AC221,0x134F4E21316A8CE5,0x5C1C915A0CBBB0CC,0xF59046DFE326400C,0x9A8D922D28901AFE,0x3C240958797A0166,0x4A397AF7284C4FD0,0xA568DA1EC5E77E28,0x33D8AEB315863A4C,0x51F91004B604B5E4,0xE1F3928FB8F567DF,0x90DAAB8AE0AB4D31,0x99B9797044C8B92C,0xE10747E0A98E2A86,0x78DDDB718F3BC297,0x5D31AD2A60AABFF9,0xE46F0A3D09988D22,0xB300FB946F40F687,0x04D67E134341872C,0x639D8442FC66B580,0xB37797D73DF79BF6,0x328FD9C4A136453E,0x4F37D73CDE204AB6,0xDED6BFCCFD549DB6,0xF91C2B64FBE9C602,0xC4DFD34E5457786F,0x3C5D175AA3D5D0F9,0xC1486F84681D1CD0,0x2978A78A7B958DE3,0xDD301A716FEB1880,0x00E0772FFFF5F519,0xCF6F749E4C7262AA,0x6660360EBB339A24,0x7D511E72755D90C1,0xE6F1C2407214EAAB,0x978263F96DA05F73,0x6C08FEC08EDD1085,0x12D323052F7D59EA,0x942BA9560C3A0DFB,0xAF42FDAF9B24FCF6,0x5847BB9433D03723,0xC4038B1E9071FA3A,0x9E1248C0B68448DC,0x134F406C30956BB6,0x85C045894B840E87,0x520E45212777942A,0x083306B56BF7C061,0xD718627EFE676EDD,0x979DD06FC16C089F,0x2016C766075B06B4,0x649877A3F96272F2,0xA2EC515D36288CCE,0xBE1543121B323665,0x0388CEDC9D89E57B,0x0D7AFBB36FFFDE75,0xAB0DE0EA4D6674C0,0x2457397A734F54FC,0xC6E9781A07A7C519,0x36953FE7EEF49242,0x8B9EF283BBFF68B9,0xCE0BDB5888405E44,0xCE6FD2C19C173F9C,0x4E4A9E3EB7B70823,0x9899917988888BFA,0xA1E33CB688B83697,0x74CB2B405E943D3A,0x1A79895E1FEFF336,0xB6E8D5CA587BC48A,0x5AF5FEC985B72AB3,0xCD8BFBF41EF3B8A3,0xA4C72CB2D93C4CB5,0x79EF8085CB774C90,0xE7B0BF4BE8CBFF48,0xB91ADDEF290598C6,0x58FDE668F6D965D0,0xA7063A5D5D501860,0x4906256C7050126B,0xCECEFE18CE2EC93D,0x5AFFCF8D31B575BA,0x173BA54B9516A245,0xB2E8BE3A882CD47B,0xE7B29AF10E470388,0x23AB07B0C2032D16,0x68835D514526226D,0x08F81364D78E074C,0x9DA37213C442AA6D,0x91B2DD0224A7DAF4,0x72B378FD46CB67EB,0xC2A8A87464298D5C,0x39E49DAEFDB4FCDE,0xC188FDF1E5B77B88,0x171D713BB3EA1DFF,0xA9A95D9FD320AC87,0xF5855FF01FEA435A,0xCE32007E0E6992F1,0xB9B75BAB8A6A8679,0xD55DBC1CE4D28451,0x016C0A0B00893110,0xAA38DD7B81B7B266,0xDE8AFDBA8255179B,0x3B1E218F9B56C2C9,0x633CD62D00B21F70,0x7878DC9916DE624F,0xE295BDCF759F6795,0xB5F2886C8CE5B632,0x0249E7F7F19399D6,0x04AD7A5B388B8444,0x04E687E8D3ECFD81,0xC65FE1BD64B76BCC,0xDFC55378670B7848,0x0E5D36A5C19A71CB,0x0E4A7353B5A20AA1,0xFCB23DE03EA50E99,0x035DE3CDD832A8C0,0xE27A1ECE7BC28D5C,0x6203E31086006508,0xD8CBB5C8306F5EF4,0x84B15CDD83F4FACA,0x446801A46C447EC0,0xC1254B8C8DA021C7,0xF11433F6074BDF64,0x021001281796F7C9,0xBC9DEC106A2324B7,0x6DD4113EABD23D85,0x406B6825169E4FDA,0xC162B4F3383F8B7A,0xEC80FFE417CF87E7,0x0472464C8F8D1D39,0x06E4E5C1DBA5F023,0x02A3C8FD62F5377B,0x1E086AAB4B63E12D,0x43EFA7B1B61AC81A,0x2261BFD2AA9D04F7,0x0E83C6D588E6F844,0xE5A12C65A00A62F1,0x4E7780CEC35CB07C,0x040CD95BEE982188,0x782DAB80A5B44FB4,0x2F149011A64AC87D,0x390225486C0E91C8,0xD6B5947BBB419244,0x1CB599980706B305,0x95FCB3503D264D17,0x1AFA2BCB8D20A4BB,0xC4B9D1E54D48CBAF,0xC31D65B4A173E7F0,0xA6205490FC89838B,0xD40AEF0414172C95,0xD3D48B5AC0EA2150,0xC0F7AE619D5FF8F2,0x55E86FFE4C3A010E,0x8FD8AB5CADF8DA31,0xBCA628074C45E1DE,0x283B4A287E0F6C31,0xE87B345EAE38132E,0x3170D7CA8CF222A0,0x6B1451181F28A511,0xD0B98B0AD8406113,0x25F5F3622E2224A6,0x55D62DE5E1EA1587,0xA067686B6C7655FB,0x8E9C0204EB674A73,0x01177F4518121121,0x3E2CAAE229E707BA,0xC3CC3C22D11F284E,0xAC53414F702A8293,0x1A234D7B00A3F4DB,0xAF8D0D7339E7C89E,0xF2E93641D00D409F,0xD3AA5E7DB11F5966,0xBEA15EA495620052,0xF8093AFBDB99A4C4,0xA3733C328FFAF68B,0xF0C78D5E2F550A87,0xEF3FFA00481B363C,0x37F012AA19FC4F49,0xBD5C77D5CDE03337,0xBBAE2D4A29847252,0x135A71620796996F,0x1B57BCBF3517CD99,0x1891A8D51D72BEE6,0x7151F0DF05E55900,0x65688CF320FD694A,0x25D5AC2CC8890EB7,0xC261933B6A7FA3B9,0x5FCC71088B3C78E0,0x55EE312D30F01839,0xBE6AD3370E2DDA08,0x26772B27906B0F14,0xD565FACC06B5192A,0x28C7E4C67E2BDF1B,0x24E27038A9D8A35F,0x138C00EC71A72500,0x7BF070BF7CFA071C,0x2AAD56F9343F08E0,0xC095E135BDEE285C,0x9F7068265FE5A4CC,0xCF816977F74C7B86,0xDF131A18ED0B7064,0x7D39D018F0522DD7,0xE6B05F40F2C3A833,0x4DC90AEA26170088,0x0A08DD35DC7AE1D9,0x91EB4DD8DD097CC3,0x3C18824A922EAD63,0xD867F6F311F9CE30,0xCCF2662BCD1F93F7,0xCF25C1CF38EEBB23,0xE5D0B6F08C3F4F4D,0x8F8EEF6497A3879E,0x00FC23C0C5B57FE6,0x742D09FFA9E4F0BB,0x1386C23EC721829A,0x10673D57D26E7117,0x659AA2D13EC93084,0x7A20A04A14E6CC6E,0xBBC3E83CDC16D741,0x2C5A87F2F487B7CB,0x9A0080C149A1A00A,0xAEAC0E3B301DA6D9,0x4BE1D18826D3726F,0xD2945AD155428AE9,0x2D7922526D873460,0x58308635C0E4BFFD,0x0D0AF4E1119B527D,0x33BCF221304E6934,0xBBC809E5A3E109F7,0xB3674B8E83A6AF1E,0x7C616D5B1092A166,0x72478202F2875EC8,0xEAB2C3D28F6ECB33,0x8D197F3154739C05,0x780AB9D6F3586798,0xBF92ACA947DA5F0A,0x07F76ACCB72B9A78,0x02F0697171BE09CB,0xBF7AF4639254E36C,0xD4824DE906C57017,0xC03FD619293CB1F0,0x631FB0E3C75611E5,0x39ABD0A57A2CDDAC,0xBF603AADB02B3392,0xE3CA9BE5BC085E04,0x8B07A310DD8BF7BC,0x1CDDAA19BB3692EB,0x16D63550CEBB2B2E,0xAA347B4F71E3AA19,0x61AA5137C248C790,0x343CFE4993230628,0x6FFEFC40B0830A3E,0xCC0DBDEAFE62A7B6,0x25D01AE8A3709875,0x33AEAA97D3E5CFA4,0x207BB90B56A5AFF4,0x466B8F5238E83D16,0xB44798D34D816AEE,0xB5B3E54766700912,0x04BB7CE35ADC23EC,0x0DD3007353A67C51,0xDEAB1E1E0D03481D,0x08891794ED181FF9,0xC996740EDAF0635E,0x98C81D213D6862AA,0xFDDDD7D76DAE2D89,0x871434342C84991A,0xCDA10A8E011CA036,0x0704B3B4934182DA,0x1634C7800F221552,0x52C7F3CB4204D418,0xA9149ADD7E9530BF,0xF078C27E11843258,0x8380904F72BCB7E7,0x558BC1BE817646DE,0xAEE0F09B68CC7B87,0xFC99E8C13F61A909,0x134E8F5F71F6A21D,0x373F866F2A2C707C,0x2413356F0503FBC3,0xE0923605CAEC59EC,0xA6F1600C2E61DC04,0xD030325E32CD31B5,0xD41B1CE574D308AA,0x5B27368051E29038,0xA4A4C7D703ACE6B9,0x9E649B88BA94CED4,0x3DB9A403D4E89E1A,0x380D927B5CE98EC3,0xB4FA3C624360E4E2,0xDA3A56A3EDBC1E5B,0x8A3DF44CA600A341,0x7A1E11E12FCDA211,0x44E51A77A546C726,0xFE1E97E16EEAFF4A,0x69B9B9176F3C7729,0x1E52ED584141A960,0x740F3177DAE50230,0x1BD93DA7C85E14E2,0x6183D9738EADCE6F,0x6E63C0E5FD990103,0xB4E0B6FA5F2585CF,0x3A71BC2F6C557EA5,0xBB0096844C7A764E,0x5328232419904AF5,0x653D741C08D78480,0x38395618DF507D6D,0x65868ADAF4A3B42B,0x57C2DC2F1055DB84,0xFBEA205FF00952B1,0x07C99DE4B4C62517,0x2C56F14B7FBD8A5D,0x57A8BCE9DF08184F,0x6CB8EEC46844F0F1,0xB150BB73559B3C6B,0x87D8E00B21DE27D7,0x7627170F192EC5C7,0x2FDEE646F15D2945,0x06BA3A7794406B84,0x19F079B3BEFEE104,0x7927F0737224D135,0x48B61E4B323C4B60,0xE2F052528E0CDC62,0x277026AADFDD6A46,0xF593E71999906A38,0x35F8850ACF58815F,0x0EDED24D34D7320D,0x7F53864526E6B260,0x31015850D78A436F,0xD8DACB7D4085E201,0x45D4DC1898C016CD,0x6BF3C5F75B97E0FF,0xE7E6DF92247DE13A,0x0D65BB0A9247353B,0xDBBC866F0613A496,0x74AE99FEAF235D74,0x719CE25396F14FB6,0xE30C292855577F2A,0x3B0EB83EA3DE3117,0x1FD0576CE4272042,0x1440D14CC965D7BB,0xF6DB4D8BE74BF930,0xF57C591DF1954765,0x03C6D585ED064E99,0xC4810EA178026AEF,0xD0E42E8A84F7F52C,0x2DE13A21BF3969BD,0x901B3D2A81A83D32,0x87E4DFF2935D1938,0x7913652EFE0BB8A6,0x5820AFF8A57CFEDA,0x19BADFB85F6C2412,0x325913E9BD8A6291,0xFEA8FDBBD8E9CE7D,0x343C8F01B6337045,0x8F0051E508EB257B,0x945EBFA82A660436,0xC2B16456B030F25F,0x4DB0E19B1ED25A67,0xE62137FC6BE484A3,0x96576C0CE281CD5D,0x0F54E25E1BC01B29,0x21B7F97FB5602B40,0xA5B1C51D45BA315D,0xEF69C2874B1FE17A,0x9A1C1BB9E50CB01C,0xB9D102B07DB07925,0x6CDB0D65BB0600B5,0x102037AE93CAF331,0xD9F3FECC305EDE7E,0x2DBDC54DA30A3AE8,0x5F7DE2E2A1D4B083,0x7FF94305D1D20E39,0x6ECA6F4C616E34EB,0x90CC7C722DB63A7D,0xEB28D8B8609E249C,0xE8072BE3BF0DDCFF,0x57FD3FC6A97F7829,0x49F0574F1734EFCC,0x5EA57C14AFFEE967,0x95A05CE136D554D1,0xC72C15F2371524E2,0x1673421C2DCFEC1D,0xFF699ED7C4E04DB0,0xB923B31316330B16,0xB1375B40A772C44C,0xFF13B173196C510E,0x32C428BF9BFA23B4,0x7BD5B3C7181A3F77,0x38EBCBE98A34E112,0xC56D75164D1BDAFF,0x4D034C722BCE7867,0xA60828CE4D68A00F,0x3F0986CD3C28D720,0x5124F612BE321D65,0x36A29B4AF8F4553D,0xA560F48EA72D4217,0x42971BFD2BC2466A,0xB14539923BB1FB57,0x7E6BBBEB03C40FB1,0xB0F2FC5C4A774679,0xABDAF4CBE7941E16,0xB7D84BCAD484F2DD,0x1FF074CCB9ABAD0B,0x59E2AFC2899D696D,0x96FA957AEE6B5A2D,0x9C1B17939D887E21,0x04894A85E335C8A6,0x869EB10BD5B15746,0x57ACC9F6285F1ABD,0xAD54B28A8D9FF7B2,0x4109C3C48E28F64E,0x5BC7D71DA9D8DA5A,0x4683938B25A227C7,0xD53879C8444AD6C2,0x600458774520F8C6,0xF0365BC4C834520B,0x224038B45A027273,0x699FC716544C2DCE,0x89F0EEAF2CED991A,0x1DA2FFB766ACBF59,0xF62F17542BDC70E2,0xEC488EC5D7AE86E0,0x11BE6154F93A0FE5,0x068A8D47333F15C6,0x2B1BEB26156BB8BF,0x3EEBE8AD9039E6D6,0x40E12F9FB17F0897,0xFB98AFB009039716,0x07D32A00E0591975,0x8A3D90A3955B0B67,0x5FFFB306CDDE96E1,0x7E4F3CE088C29DD7,0x41EA2B4597E50728,0x094EA40BC19D686A,0x0466285BC4735826,0xF4412D29933658F0,0xD481EDDF8A34CC86,0xF547FEF2E2DF4404,0xA792CD567B1636AF,0x992C4752BB8942E2,0xB287877BCF2E4478,0x769868B42D575EF6,0xD53990F20854D4C0,0x7CB79CFA58F6203B,0x4495FFD01D1381D6,0xD93E4D63265AB107,0x0ECD055EEBA484AD,0x306C9BB91B744DA4,0xFEA0668DF794F5CD,0x85A2DDCF51A2835B,0x5EADD9A525BF69ED,0x7A1380F762DA61AD,0x949192962F68328A,0xB3849353A3616E78,0xDF478EE42D201C84,0xDFF22711B8B5895E,0xF14A9C9BC270A67A,0xB2EEB82AC8A4E017,0xDC831EBFD68A7265,0x3E7832954AAA98AE,0xFFD9D73AAC617AC4,0xAF20B8A75EC4108E,0x8F1D50F7B99A9DBA,0x0A10E3159BD0D56D,0x0A9455F64A1533EB,0x5C7210F5925E8499,0xEA30186E8030DD71,0xC84E4C41F799A34A,0xFAC4D02B3F574714,0x3E795BE105F7B3D0,0x6F49D24D3EDFF136,0x137102B95D163267,0x1A739F9BD4FD5979,0xA368FBC80E55BA5C,0x9D2D12C4C4EAC5FD,0x27BED5440989D8A8,0xBEEDC038C37F3346,0xF3C1B91AAEB28F19,0x5151F3D7FCD3F37A,0x9EABB7C2E3CF4AC1,0x6BCE24315D9BF08C,0x9400D1C51F95F371,0x1921E931345D5DC1,0x92AB3CC459FDB0B5,0x0C166B711AF63BB4,0x78965C0C70696D02,0xFA27ED676A164FAE,0x227D9B1219B674E4,0x49A6F6937A4B4AE5,0xE804F628B9D48D84,0x13EFB47CA3C358D7,0x279925221B665CDE,0x61B2BB52457FC454,0x0869CAE40244EC3C,0xBB8D341700EA475C,0x5690779D93528096,0x10535840F3DC36EE,0x71FF64AF0623725F,0x69965C183F51F1EF,0x857040E7FD77C33B,0x043CD673B4C1454F,0x7601EA3ABEB0A957,0x805DD13A813AFDC9,0xDFD53750CF55FF04,0x37F49A9D077750DF,0x0939BD1866B03E58,0x95C7D350CB5047F0,0xE0CAC1FB4EBA79D1,0x3550B881A80C0191,0x61015A424E5FA09E,0xB6B662C18210B181,0xF309A7D714FCD632,0x3E4F8465BFCE409D,0x2833C76F58F48E31,0xD14F2BE025FB2682,0x32F6D9649D9FBFDD,0x851C4609BF6C2748,0xA32CF8FC14696DB3,0x1637D6F4B5979368,0x335FDBD781B3C5FA,0x1FEA9E913C8ACF3C,0x13E26BC708795CA7,0x2B1111F18810D36B,0xE39DCEFF0AF55952,0xF4C10E98DC052B14,0x1AD9973990D08277,0x683D7BC21EAA4018,0x93FBBD35BB6F1AA1,0x8FA6DEE5DDD29676,0xB52E685BB97E5267,0x59ED61915E228695,0xFC53FF5372DA91BC,0x16C8802BDA8F3A26,0x65B82CF9F3F97867,0xFDC10EF751D8E7BE,0x1B9A76DE6AD0A564,0xB16D3E990B0D9B59,0xB9B7ECF5EFF92398,0x3E4E5D8C4DCB5FAC,0x9027D4091C23017B,0x90A2228CEEE9D904,0xE66A454E0EF38CBD,0xCC7E910E4E0C5BC2,0x1823131F7A207B94,0x40DF6D2CBD0D50D4,0x18EE2D52B46E3D8E,0x884FA7FBD4C871C1,0x956C21974EE0FD8F,0x17F0EC5F5384FFFD,0x1CF806F176378AE9,0x06F4986FB093C74C,0xF6AEDDA28355608D,0x7544065D9F656A41,0x7C0F07E40484D51B,0x7DE1C68E9DBFCCCE,0xE0FDE54C1E19CE98,0xA30C59FDA67D0D26,0xB5A6F874F35BDE72,0x2820CE59D0997AA8,0x593FFCA189414348,0x5384F371440A66F0,0x4BB1B392D403CF98,0xDD6208358F484D69,0xE33D77F753C48729,0xF9DEE0D6306A76A5,0x1902F84F019E8790,0xE191ABE2D0B8F45C,0xAAA78E249AED55CC,0x4CA5502D5A405ED6,0xC5435E511A407D53,0x72CB0CE656340565,0x9259CED3B7815F8C,0x9AA7EDFE68182051,0xB593F2C099CAE097,0x3BCCF1B129CD4DFE,0x9D2EC4CC6572D374,0x364A1EB556146314,0xB99064691EC73C4C,0x2F6605E90FE9B91E,0xE7FC3DD9530B1DDB,0x1F008B9CE0263F93,0xBEFBF1349CD9784B,0x25D96F695F68D275,0xA46547C9FF31BEFE,0xD50FE59D2DE3E153,0xADCC0F9EFD320792,0x4955F7EF372AEB2D,0xFD0B01FB08CB948D,0xDCD54FA70C0DE532,0xB9CF306DD3EDA439,0x233B161FE83471CA,0x7BF291B89CDAA835,0x81748268CDB97142,0x50816B0FEC4359B9,0xF77C51D1B0AA0520,0x28A5B312FCEAB840,0xB2978E6A6396C10E,0xF5BBC1ADF4C2CE51,0xD6E2BEC4AFF91F29,0x41909865C5E2C2EA,0xD4FBA16732540E17,0xB53C0EF9FB3C20C9,0x06B0FEB004430AA0,0xA07B6EF747F0694C,0xD1F901691CF28D21,0x08BC5AF130A61584,0x58A9D6C74625F656,0x6430CE266B979B3D,0xC65FA43AF7182904,0x666C68160AA1DFDF,0x26B98029C7DB6767,0x1B04281FD94D4D05,0xB77AA15AA9D9C820,0xFCBB2A5C51B072F8,0xAC71E34F9913DB67,0x422DD9638CE16EA1,0xEE3A0BAAE04B94A1,0x0EEE59FF7BC0A0E6,0x174227496F9871B9,0xEE6CA89CDAF61E65,0x8E6E51D15EDCEB06,0x543A38816F20685F,0xF4A78B48BD0248CF,0xA1EE40C11FAF28D4,0x9BE391952E9E9336,0xDA2FEF232CF1B876,0x95DE324587E25CDD,0xB14F438FACB1568C,0x3D761ECA632C9371,0x5EDDCBB9DED787BE,0xD71DC10CB50B0E52,0xFE345858B29F2BBD,0xE74B05E465BB1474,0x90C16F2425ECE161,0x2095E3786CA1DA68,0xE88CB50DCC7946AC,0x9755063E497CE046,0xB757489A47DAA442,0x0AE3B3E1071805D1,0x4045C2A37A6A7FD4,0xFF890CC37611D6F3,0xCEB813272B0A295A,0xC6A1FDBDDEFB94C0,0x139E7297244D6D19,0x7A67A8560670FDAD,0x501D1C14C2C1F45C,0x8EDF5CC1BD45349F,0xA755DBE527CA53D1,0x30E7C3C74DFAE458,0x149B6191C10E34A7,0xF48284B9EBA1BB2C,0x7406A5DE7D00273A,0xA5D2D9E46C3EFB0E,0x815FFE3157D37DC2,0xE8E7EC04ECF300AA,0x8FB6F89EA385414F,0xF98E6D142DF781F6,0xF5DF4F5673022C42,0xA8B896C4E5C15F27,0x928D0DF6F89CADAD,0xC30904647A21AA36,0x67BFB7E7CF79F575,0xD30A6A3E93F38952,0x313FBF3DE7B6BADF,0xDC90CE6182429CA3,0x66C23F1CC4908232,0xD92BCEBB3B9976EF,0x4E94C59646B4CB6F,0x63C580038330645E,0x4A6DDFE593B3DDE1,0x683804444330900D,0x792A85A26A39A189,0x09205DFD22844C17,0x408D06F565BA99D8,0x98B2F8D65D817E0E,0xA056888D38FA864B,0x95013ECF4C918200,0xA437D929D6720B07,0x38B3AECC8F5FA733,0xF8DB913B84B064C0,0x7A9B5228227A0903,0xDC5890339925470D,0x387C6E498B646E39,0x53718C898BF1BF9F,0xC4C7CB8EF409CF38,0xD1ED67FEDD30530C,0x17D9BC305CC198C6,0xF6B390B591BE6826,0x96B6C35F5A397FC7,0xA3C2A695E123272D,0x4D7788406AC92052,0xD01671628325F939,0x32EBF4F9C103F28C,0x44C12A79FFB7A538,0x68D70686EA4B9449,0x8BF417D90F75B00B,0x33A88DE88DFB4054,0x856CC9A7AD890F0E,0x6C6233A0A22D1E4C,0x6D48E164D3CF2397,0x55A8B6690BA11EE1,0x655ED0C6303B87BE,0x7999A9E7B6C27693,0x0EBEB84C9218008F,0xC105864E7A0C02C3,0xB0A76119F58BD0E9,0xA35A2CC4283E929A,0x2B8916BDEF09C674,0x57B7E09D8063A6F5,0x07098079BAD9A95B,0xD90E2663689CE59F,0x05BA8E0874234567,0xA07E98BD184B9111,0x1C0458935E40EB75,0xBC214287D11A10B1,0xE838DF02A691CE94,0x8F757CDCA9B353A4,0x846A52E37B822F66,0xAFCB1BA4C626CB22,0x7EB913C96BE14E92,0x29820A68C34A67E6,0x329BEE238DE04100,0xA71B1E8D1449981C,0x06BBCF6672DDC5AD,0x6B9B5E9B5A0B4614,0x446406592B292322,0x1A49898374CFFEAC,0xD4AD97794CC568C8,0x8BD44B82B2137B81,0x4DB0BF0727C8F6BE,0x3C6125AC279CD22B,0x4FCD27395C52460E,0x0C4A5507E029A360,0x832B4F9CD6216FC3,0x8ADFA50EDA59ED1A,0x378E9CF4F76015BE,0x2ED1B0E7066A6C5C,0xA13CCFD31E8815BC,0x5C9CC64541DECE87,0x41C3D1DA3472328F,0x061D8D0596C3FA54,0xB0E087135BEF53F3,0x1DEECF4C6796A650,0x3DF5273529696E0D,0xFBE3F25FC86D73D3,0x3B51FB1D39BA4BFC,0x9BF62BD7F73FEF06,0x2212460DE1750577,0x2F33A204FCD45389,0x304D51381F4E98A6,0xAA00599AC35E1401,0x72BBFEAEE0CB4F88,0x99BF729D916ADEAF,0x7EFB6ED503BF700F,0xC75B49ADC6ADEF43,0x03A3046032C10FA0,0x2AF28003FC5052FE,0x09B7A8C5CB960309,0xBCEBE75B08B05467,0xA87AA10B789AD2BE,0x3722373C3BC59048,0xC2D3EE1B2CD0717E,0x5A13E5085C437FDC,0x0DD043F1E4706947,0x9B150C34C475EFD7,0x17BBC8C5262D0BEC,0x8E2A275D15164886,0xCA644362C714306E,0x00D5EF37895C8808,0xFFD751A0627576A4,0x26D5D7737AC3901E,0x2DE4B65667E85C70,0x81BD879EEAB9F7D4,0x0C0FE3F16C9EF988,0x227CE4C64A078857,0xA392CB63B6985F5C,0x8BBEE9A0602716FC,0xC45865AADDD5D52F,0x19F82DEFCEDC290D,0xF35696813AA1976F,0xEAD77EFBBDF2185E,0x199A1C10CD73FC37,0x29FD88726A772DEF,0xFB8FE5D72921B5B8,0x86ED653FC74A8F1E,0x1232A048248A2461,0xC92DA2D932A6361C,0xD61C04D7DBBAA7EA,0xA9FBEA05DED7B085,0xFD93470FA5FA19EA,0xD20D42DDF35818C7,0x015D46D4EE3BB82B,0xBEF6A2A29E7291CF,0x395836C1206A1E24,0x9EB50D5162EDD921,0xB962FF206F15A355,0x2B3D1C11010A9C02,0xB7265F5DAA5849BE,0xCE4951610D12FE3F,0xBA0B256465A6C716,0xE0EA8900F80F6C9D,0xFC296FFD3286033A,0x4FD35DDCE7B2E2EE,0xC5A173A70834FD11,0x8B169AB09BB65C42,0xB8B527F3497413DA,0x4C747A86F1FF845B,0x34031578F9117E85,0xF460F35EF4B0BBE2,0x3175A559370D9F15,0x76A87CEE5C26E7CF,0x2C64CFCC8F9CCD28,0xD54D9351C5F2266C,0x8D73EEEE15C931D3,0x72DDE8427AB82B9B,0x94A093E47D849355,0xBC1167A3551CB9D4,0xBF5EDC65EE7464F1,0xA6BC2AB57A8DBA3E,0xF474B9041A755FA8,0xE8C9A05AA952D498,0x0A05CDD7955FEBDC,0x861EAA9F12F62151,0xBC0524213C07BDD6,0xF783B1C0228628E7,0xA605E048B587E493,0x5D7E7D4C91532C09,0x2445543368CF55C7,0x180B0149B074E721,0x96556D364D2991ED,0x0ADA611C8BA8C65B,0xDFAD47DE5B442A2E,0xDCF34EDC8DBB8A3F,0x57516E0D5AF7BE12,0x46070154B6D2BE03,0xE72B2CD1BC5BCFEE,0x39F80CD0423C6D58,0x25755AD9FBF58B04,0x42F57EC040A28AA0,0x3392A27E479A9DD9,0x3DD83BE11CB9F700,0x6D7F3D2D01FD82DF,0x5E50C8333CC09DA9,0x01B11C5AA77DF08A,0xE869C3CB7C5BE962,0xA905D856419723AC,0xCC9D06736AAC6CEB,0xB51D2F46B62E158E,0xF3CF8D6EA06FBD44,0x8DB6CB1B1414C394,0x197442F77CD720C1,0x45101D31C24BCF2D,0x090BF2FDA6B67339,0xB2907DCB268AAF19,0xBA63EFC341755965,0x8009E708B1098EC1,0xCFA5B77BB72A24EE,0xAFB143A8E45A210A,0x6B56760D41BF5D93,0x28CF920B2E0AC482,0xF8735C2CED9EAA49,0xE490397A39033CF4,0x35A820F713ACFA67,0x4423AF3F08BFD568,0x3E3BE952CFC4035F,0xE37EC6EFC28D3CE7,0x4223BC43FEA5C1AA,0x98B018888561F638,0xE4B39016F4734A41,0xEF0751764292D41E,0x68871130B1584C3E,0x4D1469E8803FDE93,0x3734F0F331AC9EE2,0x1C0537E9B15AEB71,0x3B33817A71AC027B,0x900C63CB408FB41C,0xD6514EB6A50110D9,0xFE44DF41A5610F72,0xC41769C1237EFA8D,0x81DECD99256B77D6,0xC21B58DD52E322BA,0x1BDD1AA072B8C21D,0x19EC973CAF7A4D9A,0xE18235148ABD7AF7,0x5FC92CDC8E2D1162,0xC1BBFB06E6A93C6E,0xDBCA3EC87EA4443E,0x960D7244B1159AEA,0x51F8367AE2100506,0x15A938DEEA3D786A,0x392A4671B1116BCC,0x4092176B6139EF21,0xE1405925D0AC4A17,0x444FB160594164F5,0x25B35C58D51E59B6,0x84708FE20F25E94B,0x161E6A085B4D9A25,0x4E35E2146D945F04,0x29D3549482AE72F7,0xF5DD64BAEDCAD1B4,0x5222DA7745AAC9D0,0x073C758E8C82D23E,0xA5A3D73D746FCF70,0xEE983701BB4A36C5,0x0246A634C4C558AD,0xB03E40D1C1F836D1,0xDA64BCE0D9325612,0x8E332A24F5022CA1,0x86AEBCC8B0EBDC54,0xC72DD6EF57B497F6,0xC637CE0C0835962B,0x9B2CA40050373CE0,0x728273CE49660196,0xDBA3D65D3EE1CB40,0x31614A5410B8FA3B,0xCB33A3DEC2321741,0xDC9AB6C83166A7CF,0xFBA65F199D1A5843,0xEFDC42D8F14827D5,0xD9FF3C205CD9E92B,0xED3FEC4DF03F5969,0x60F828E67E35577A,0x565EF266AF36AD71,0x0D2224F582FC95B9,0x418F35994E7BF337,0x16249F0F5F28B855,0x7CF966648CBD152C,0xCF1A6B6AE59A51A1,0xF186F7546827DCA7,0x491473B87A5A5E69,0xE9B18CE8062901E7,0x06DBABE75D4E9E59,0xD00D0D84A197355B,0x94FAEE79718C10AE,0x934B4C3B3987E047,0xF6E0055546651405,0xA27A17F32954D98E,0x662FF361B0E4387B,0x2A7FF56A7256E95A,0x14336A8F6052382E,0xD43AD56DDF5C915A,0xDFDF3D02DB695EEE,0x4A78AB81A5ACEFFE,0xB517CBE2D09B408F,0x28A2380843DE5303,0x9EF92E34D8B5E3DD,0xCBEB3DBDBF873AE1,0x6733E4D462419D96,0xB02861DF4D074421,0x5F2ED95444C5DB29,0x5F1D3AC5DA8AB701,0x16A52CDD318FFE5B,0xFF1FA1B9F572DD21,0x45C16E199203DBEA,0xDDBD87382A646FB4,0x325BBA470C79B934,0xAAEBC478D3B1D281,0x7407663BA60922EC,0x2B6BB15FB1956005,0x0C498EB625C8C8FF,0x423140B586364DD3,0x50EEF312DA3A1CDB,0x075A43004A52841D,0x5DF4FC101E0FB296,0x8EFBE5CD861607E8,0x6E682FE52B39402F,0xD3BAE9356B64AC96,0xA8CDB62831D72CC2,0x59D65C05C6CC5C40,0x6559B06D44410562,0x18A29AD71F2E96DF,0x8562C928E6907CB9,0x1206951EFDC8E1FD,0xE89DD5A14C25721F,0x675939B99E5E686F,0xA72C85F942D5ED85,0x1AA518ED1BABA9B2,0x945BBACC2A0726BE,0xF104B8B0EDA19620,0x788610D350664140,0x2D29753BEC861DE5,0x0C73BCBAF4812865,0xA48CA1164F7D23CB,0x8E582E08F40F828C,0xC59D186D3CC4792F,0x104DBE430E55C8A3,0x0F0A5F9F9F7A33EB,0x43EB4E2864C233A7,0xD18E351C46E0FAB1,0xF5752B6E7DE148DD,0x460CEA42DD82ACD7,0x72FD12A389E22F95,0xCEAD0750F9723191,0x0E8243F88345F6A1,0xAE2E8A59588678B7,0xEFFD880EC8126054,0x22AB1B487B977A3B,0xFCB2DEA89D520088,0x109BE1C21672A3D5,0x71C3F76E4B34D4B0,0xE562CC9183287CBB,0x40A2C0439F52BC91,0xE41B7FB97923B036,0x88794C2A728871C8,0xE2BC910D1B1129EE,0x401F7DA30041826E,0xF42A5118B8FC8697,0x8C7C661519383B56,0xF16D57FE41F2C729,0x53E5A90F19F1767F,0x8BE42CBCB4D58725,0x706796520A824B2D,0xDD0A1805D7BE9187,0xE46DE76E66DC63A8,0xB16E783EC0401F9E,0x0F9D8B77CA0CBA0B,0xD976B18120CD82CC,0x4B4ED176708FE5A7,0x00075B97AF7143A8,0x7651868D6518D2BB,0x6578A03CFD3C331A,0x28565A5005FFE1F0,0x8278AFA9F962DE0B,0x663EAC031BF89C49,0x460EE4A9B8B2501F,0xE14B0F0B28A57EFC,0x2FCA0840F695FC67,0x96DAB7F8AA8FFAE3,0xA6F6CD487639DA57,0x5C4535AA4F2E9CF2,0x306AA984028201EB,0xDDF64B09F852C318,0xB291C89B5D6CAD03,0xF1E683ECD2BB45DB,0x8118E95AB13FC466,0x8057C19F02737A89,0xEDFDE7F6E093BFF2,0xC8B6081BAC4DD790,0x07A8F6FC79509069,0x91F02278DFF453B9,0xE9BF264C1B70DFE6,0x0DABAF89BBA3C3F8,0x4C13EEFA510763C5,0xE72AE9873E4BCD5A,0x2A56BB3EAC03F38C,0x9F7B24B6EE233997,0xC222C9F29B59B29F,0xC504732A60F7A17A,0x6C8D89543E3E376E,0xC5D155EE6FA36535,0xC13D5CE6ABE291A8,0x4C01A977A2FA901A,0x0DF02A9A85DC7ED2,0xF54766E8AAB723E0,0x6B6A3591460AC1D7,0x48A5625B4D0C285B,0xA95C626B2EE316AD,0x777885FD63FD429B,0x8E6CAA4BA6888510,0xEA8E7232D07597B9,0x1EC570C47C014B56,0x4315DA8C64C5ABAF,0x6194CDAECE42ECD9,0x0D023FB91450B368,0xDAED044649E7903F,0x6D551DA951C7DCC6,0x1A512F07D455697D,0xEBC8B51B8352947C,0x5ED4D0DA6EC95941,0x1F102930624F7E48,0x4E17EE51CAE8256F,0x3E5014C212C60A82,0xB884EAF26C56DE78,0x39F79265B7650BD3,0xB8FAE3F8D61FB7B7,0xC58752CEBDE7E179,0xD65799E769F3467E,0x09015E8A810D1578,0x264044FC244FC33B,0x1A5872BFB050C399,0xFB75E4142E15DBEE,0x617601C2B2235FFD,0x39802D67280EE59F,0x21E6966C8C4AB614,0x105C2977018D5468,0xA3CDDF56C812CC62,0xB40C62A65A0D0D06,0x5DBE3FB29C24A193,0xB557A7258E4E3C9B,0x5BA81D18605F1C35,0x016C882CCC2755FC,0x57DC51697852313F,0xD4AB9C1109F4986A,0x60491809679C3AAD,0x2DE365AF3629E5C0,0x9F9EACC7680392C2,0xF463187547D577E6,0xAF34554E33B076C2,0xD2A0DC6AE0FC4FB1,0x245FF2D7D4789285,0xAC8368EDA9350E2D,0x0F07A9DD626C9A11,0xB8BFC332C4502D4C,0x931BE13D8C637E8D,0x3F35B0B3DF9DA412,0xE31BE87115C454A3,0x1C3EC32DF4CB5BF9,0x0AB1EF46B8363782,0x886B64AAAEE76B27,0x616038A761E43BFB,0x5150F623BAFC1751,0xA54254AF52CD9F5C,0x59ABD12B01246B1B,0xE000021D3C9CAB26,0xE57A512AA5D003F6,0x663F8F02F401503B,0xEC112B4AC86927C5,0x991469028218C4EE,0x1208048D110256D3,0x61CEB96145074BA4,0xBDC99F76002399F0,0xAD0CE5862114E6FF,0x02D5918CCE046FBA,0xB3877569ED38578A,0x1AFA8D130DD96B5D,0x3CACD6311F9AECA0,0x17B79DBE2C92F0C7,0x1F7D0051A40B6B85,0xBA23DAE9E724E2CA,0x88B678A40B5298B0,0xCA56BFEC2EF95710,0x06774D350AD3056C,0x9EBF15DD3DAA1FD7,0x8D8865AD335BD973,0x65728DB243A1D26A,0x80A1811795EFDC58,0x651606B3031C7405,0xF4075C6B7E04CD25,0xE94134C43C2D3AE0,0x3E8767028E44A399,0x59D76B7F9A170D27,0x3F06EAA3B56B9627,0x919C905F324FE38C,0x3D442F2B86BD115C,0x493EA47D4D943C72,0xE1948B2877C7060B,0x69EBD292C9E0C702,0x42CDD074AEF47B20,0xAB309D396B5D9CCA,0xF4456B11CD3F08BE,0x2994335ACA80B4A1,0x14B3059EDB0FA755,0x060F1F717A8F2507,0x8E96C927D1C90EF6,0xD5A1AFA75D27969A,0xC9058FC28BA84935,0xF0C50759742FDCD0,0x554EDC5A998A6AE2,0xF8B727F15C0C8023,0xB179BDED56D2EC90,0xA4C604D1CD957796,0x8E875860745E638A,0xE17318DC968C6F53,0xB3C75BBD9BBAF468,0xC6FCF522A2521C3B,0x367F724CDB9FB278,0x26F5B431484D271F,0x3149BFEAE7FABC12,0x9AA27C59001EAB87,0x77BF84E54B1AFDCC,0xF3D12A56A41B37B6,0x5273B751A39F4EB5,0x471F1223A65FBD9A,0x49069426D74B7799,0x84FCC51F02CE2959,0x112FB1809D0D3B5F,0xF95343F20BDE6218,0x0BB6ED44D7141AF8,0x53F8E3653F369058,0x800D0A589941995C,0x9D872865C4D65C29,0x1141DBBEDA4DA891,0x227B01B39DD0F9C3,0x5CA70236E8DF552B,0x56B9AE25A03B870F,0xD030A817C7653689,0x17941B09F5B404A0,0x36C7C98C59C26A59,0x3B87D2752C1A1B28,0x0A182A1AEB2F94C6,0xA23E7B97BC7DC475,0xFED85D06D06D80B0,0x5001713E2B1222C8,0xB4D4A531D60412A0,0x65FC8E1C67F7207F,0xFBB13A17AB7BF5C6,0x0EC7484766F1B5C0,0x55978DE37A7D5903,0xDFC5DEDF914DB800,0x80DED753369375A3,0x2E1A378F120A321A,0x1B92E66C9D60104A,0x2EA9C2E15BCEB4DC,0xB1D18188E21FAF75,0xF094B0EC4639DC08,0xB648E730070D25AB,0x770405C8565EC403,0x0438B9CEBDC2C47D,0xA745CCA13B15CC1D,0x0446E775DA688787,0x469AF56052ED849F,0x6001054BB8DA49B3,0xB7FABC46B94C9163,0xEDADB9E574902038,0x95149B347A5A7276,0x0C83DBCFF88A0A86,0xB20456E837FE9F70,0xFE9F0567A5A2F3CA,0xD23CFE389A902A2E,0x8F552B3857237B27,0x3B220F505A4AC85F,0xBA4828C6E804B0E9,0x740BDD4716A26012,0x1AF31B9C3D876216,0xC23D32B21C7ED6D2,0xE9154B37C911CECB,0x4A2B31F54315C074,0x1737F5860049CC2A,0x9B5F40C2CC12A450,0x01E7D86EA6CAACA2,0xEC8F7940718FA2EB,0x6F262D2722146F81,0xB3BB1E361721E208,0x6DA0C323F0C27447,0x8168BF3432FCC314,0xC5C4CDCCAC51A58E,0x18405060DE7B5864,0x3E1C23DAD89A091A,0x9DE6811CED7F7DBB,0x30908868B9A84143,0x1B5E906DC09E3B58,0x3198703C39FA3D16,0xC545DA99E8C41AE7,0x2422705398F9C9EC,0xFA304A09C977D6C1,0x3C0B77E55C0A3B6B,0x614C33EC3E763F63,0x4E7565C18B137377,0x9C9828A7EBCD40CA,0x889E88D1547A838C,0x3A73ADDBED7B9EC8,0x2A8EA9550574466B,0x067CD3A1DA04E27C,0xDAC0DBBE961A058D,0x48D5CE83CD3B282F,0x45C7817DFBD7666F,0xC2EFB87A68DFB306,0x0553D9E85A675E44,0xFC16859EC429C915,0xE9E46911E550E65B,0x9D7EDFAE97B75B85,0xAAACF8D88E260371,0x7D75DF039F845B37,0x955EAB46528CFF8D,0x661865BD370070C4,0x2C2DA2A326698CA0,0x451D1D775B939525,0xA42F4AE989E77B61,0x71772626326F72F6,0xCB8B5457E0F7D00E,0x2D26B3EFC8D08625,0x3983A5E1DDBBC7F4,0x30C87B7EEDD17C7F,0x19EE5A258F814139,0xD5AB133A0F76B9FE,0x060FE5806AB6B6D6,0xE2D89313AEFD1EA1,0x793BB8B0FFA0B136,0x4AB60D56D604FA2B,0x4162B9FCDF7EE853,0x1531EF7AEA3796B1,0xB3707504CEBD011D,0x779782D108594EBD,0x50EAC37FD6B1B319,0xD9EAC6CA905D7156,0xEF702F0D6B298D9C,0x15E57DF043807D42,0xCA319085E082EAE7,0x4B5EA4521DF639C9,0x751284259BC2212F,0x104D42C945FF45F3,0x7178028E2557DE95,0x51646A6EE50E6EC3,0xDB9FDBE2DF8DA922,0x86A556ADED542962,0xAB805A8E53410C75,0x295FC4ACD4A18EA8,0x186DDDFDF053C76F,0xB9B150F93C0025BD,0x51A7B2D269D6F3BE,0xA2CD4C643E59C431,0x8FE21D3340467171,0x3A59AE55A12F463E,0xC76A3DDDF2DA9952,0xAFBBFFFDD208737C,0x6438AEA8747B8D98,0x64FD97E49298EDE7,0xB95AE6FEA1097C33,0xD8C429283949F5BA,0xD8B01B1AF8E403C4,0xC01C957FE83DACCF,0x2E29D9FD73998C68,0xF463A0FD6E179997,0x7B0260D12AECF0D2,0xA9F5E05BA8F0C879,0x650BE31E7B4120B6,0x5DBCFFADE67DCE32,0x7C4EA7E61CF86D02,0x191698EFF0AF4CDE,0x6DEF13A18ECCA7D3,0x2EA18730E57EA033,0x2AA410B07B793212,0x12BB57E14FCB93D0,0x6B34E57FD91C15ED,0x373DAE5FDEAD2279,0x88E292DCC78A5CAE,0xCEB8E08301E8FA03,0xE5888BD49F4AF53D,0x867CEBF64886CDCD,0xCF90E3A744FE9CAE,0x3FC2A5918E5B10B5,0x4FAF21E65C05F6FE,0x38D5B5B641D3DB43,0x40D9390B68E2F38C,0x40038ED265729168,0xB3D829CFD0C43C1B,0x922E607214EE88D3,0x90BF480E01CE7C46,0x07F0342A0B756AEA,0x709AC78215FB01E2,0x79ABD9E24FC02F7E,0x52E86306DAA6FCD4,0x3C613ED913EDEC6C,0x83D48BC1F6CB1CD7,0xB1276BF073D17914,0x75098713BBA8C71E,0x1AB0A2A62B5E2180,0xD35AC8D32961B2C9,0x07C8C19D88A6C104,0x52147155F1E1C4F3,0x146E643AD21574A1,0x56B3877FAC1A1DAD,0x8B426D4911B0EEBF,0xE9CFB1FCD5F0FA45,0xD3D35FF461B46F20,0x2C2ACDD64B9FDF9F,0xE6359206144DA072,0xB0D641B70C270B28,0x0872034B0B9B839E,0xB08A2734CC01ED50,0xC5766D52D3B2DDDF,0xE2C871941B449557,0x721C2CE99EBE6D6B,0x04EC0CACF071C6E8,0x19D1E78F207E57BC,0xE5D18A5A2BFF40E9,0x54AFA9F759E1C364,0x85CD29B3F7BA918C,0x750713DD7A0A7537,0x8D3B49130B0EF04D,0xEC323C02698308F1,0x0EF134413D757EB0,0x58E5A9251E91FBEC,0xA11CD5F72B4C12C4,0x5AFBE67F6291F48E,0xB4688B888D1D223C,0x3658B5B187F445AD,0x2F06DEB46423A1D7,0x54C9050786C47169,0x9BE7933057FAD961,0xCAC9CBF47874F369,0xBF6AC33F51FA4E5D,0xEA67CEE5C1750DB0,0x48B6A0CAE66204FF,0x3FA359BAD821FEB0,0x5DC239189A0D6554,0xB6BC8C2B83CDE051,0x92B78577F770998F,0x009A94204559B4AA,0xB67577DC3E155278,0x9D704000863E3B4A,0x1A54E284DDA261BC,0x3F968E5AC711B2D3,0x608536A4D080E40E,0x9F7F6C4AC36514D6,0x52B331CDE80D66CC,0x76C309662598E036,0xD1737AF4B1350520,0xA0C67F71119DE1AD,0xB35ADADB96841C46,0x7F58E402235FE58A,0x8FAEA2C0CEE7250C,0x3B35B5A624B04634,0x0B8E7F30837DBBF6,0x370861A1B4D2F611,0x8CEBED6570678925,0x89409E2D42E07040,0xF65981F9ECA95D21,0x66AE2AC289352C71,0x711F8F41863485EE,0x58FE312B2C1B12CE,0xF617BB20EE6C33E6,0xE7CFE66E0CED2656,0x43F5060BACAA51E5,0x190122AC44980A74,0x0E02E547C1FCC0E9,0xF415D123CA127966,0x489CB6031212A291,0xEA145CC407987C00,0x5665A0C1F46C2987,0x82BBE97A20B25FEF,0xD1E7784708E0B073,0x7EA2249D767B5BDB,0x2C46191507E3A0E0,0xEF3C632BA92FF2B0,0x46068031B83EEA00,0x2E42A6AE30BC77B1,0x535CA0E89652457F,0xC85A46C3589F969F,0x44E71EEBF1F60BD6,0xA3D7C06F3E830246,0x5BDECB610E524906,0xA55076B8858125B8,0xCBAA86451B17D181,0xC7B85E7ABDBEB79B,0x03EA8E45EF1894E3,0xDA9F2448A0BDB55E,0xA9346E9D27E388E6,0x6BEB8643D390D17C,0x131AACCE1D9157C8,0xD50B700D9242EA38,0x6CA9E040C4895DEC,0xBE9C6C16BD0D1559,0x37C3DBBDA958BDA2,0x00504E55560EA6D5,0x47AFD77BCE36C807,0x72940EE465DF9763,0x136845458F779411,0x7CDC9638DAFF1884,0xC9AC7FC01E447349,0x83A174955F88FBC4,0x40C30C3F4324E5D0,0x3A997243F524EAD4,0xC2A62365F3B4F196,0xAF789FB4EC832190,0x800FC6F8FC68A7F6,0x575DEF9253BE50E6,0x032873B87A027E45,0xC0FDCE31680341FB,0x187A103F33DB3D72,0xD2F7F0CDF15A51DA,0x64DD396CB656433B,0x1F3EAC5FD0F4324F,0x7771B1163D75749F,0x835579FF9B439A82,0x4F9431639AE79BBE,0x6DCD90E33A9B7FF6,0x47F80BC1FEFF81E6,0x18452DF38673FFD6,0x71223E2B292813C7,0x50997286C1F6B966,0x03F8C6B9F519773E,0xB9A6C05255185A3E,0xB12BF289C559E243,0x21871FED327C2D3B,0xC6BAE0EC0482365A,0xA4A22FC8CCCBFF4A,0x488B321F16DAA98A,0x9F8487C0AF3A3879,0xC6E90D29D50A6075,0x2A13E29693628451,0xF88540BC4F3D4C88,0x547E63CC03624082,0x73BC15E02EDB1FF2,0x3904A323C631DE27,0x0BFB6EBB46DF46C9,0x7934361186657E69,0xC84B7C83F90D1983,0x5C67DA5C1CA704AE,0xD2610DFC908CFFC7,0x679FC719F3C7164D,0xCC2FC0D267E81698,0x66DBD0E2A8BA2FDC,0x5C2766FD12494377,0x528A9837AC50F74B,0x737FA6BF82AA5CBC,0x31CC7077AC7937EF,0xA5C53D00F130ABBD,0xA45FC1FFF3A747F0,0x3374B9846813299D,0xE393E2C6777117CB,0xD65B819CF8225723,0x4934DA0B9FA40062,0x19638FC4E2FF5701,0x9B925FEE3021B58A,0x240396EC4708391A,0xF84ADE29304C6809,0x3CFBCCDE546DEC6E,0xDF89BEAC508EEC70,0x3CE472B41680A385,0xEFDA572F61F6A80C,0x26C7D61FF30A883A,0x319F69BF7C11C45F,0x48EAA2F75894C475,0x500F838DE2F1297A,0xA3300A47E7C7E80D,0xF62FA31C304D3413,0xAABB2E37E314E272,0x983E3437B0984264,0xDBB9BC2F62ECD98F,0x9CF7A6641461B269,0x816A53B800CAB4EE,0x8954BFB93E0F968F,0x31949E5D3036224F,0xC5CB043B1422F876,0x1BE1D386C582B7F0,0xBB8EB5E066488937,0xC609CFFE1F374631,0xED898D235BC31FAB,0x1D9138DC94CEB47A,0x55C1B7796233F712,0xC5313A9B21E4F8C9,0x64C3EA4921F6E5E0,0x2193F0FF57B4190E,0x341932EB4EA61287,0x7558706AEC80E8D2,0xCD5D3604D7221C31,0xEE272F40AEBA1874,0x98E657179541882B,0x359DE3AFB59D9854,0x7B4E8DCAB3549A00,0x78E17537E1F74D56,0xFB66B6AE6CB1E8EA,0xB1ABBC9FB4392537,0xEB05A24AA0517F4D,0xCE52D80564A36964,0xF690AAE767F33389,0x5E1262A75AE4ABC3,0x38493F33D8F34CD5,0x20941B49A8603C63,0xBD3BAFA9872545F3,0xF7EA03EB9E41625C,0xA73857CD8280C510,0x52B43D13A326FA7F,0x3A4CDD391DA8BCF1,0x241516F4EDB8115F,0xCAAB930756582C35,0x8D12D4F6F47575F6,0x53F23207820AF360,0x006A60F261A76791,0x5939AFF422A9C9F2,0x24FDE4DC3C7FAF84,0x42CF2A5304FA3DD2,0x39C4F9DD2AE95F86,0xC105218CCB8658B4,0xB565EAE7F336B629,0x09331C29DFAC441E,0xBCD7241C801ADFDB,0x0FDD9607FFD41C52,0x5A34652002A757B7,0x87A5E5B4AF50DE85,0x5CEE5D4E6A424D82,0x8D331CA166D08688,0x6AA7373F1A6D3014,0xA83B33FA46AA90DD,0x725DBBE0ED4A0047,0x62E1697917235179,0xD1EF3F491E72C83A,0xACDFFFC4756DAE69,0x31491620D6797794,0xC699918A52E431D9,0x6781B5A58FC4914A,0xFBA817801305EBE5,0x3C99F2E8F5699539,0x28E9EE23DC16A1A3,0x5A86E0AB39B807CF,0x0CE3ADD2209B7C6E,0xCD3C65CD863735C8,0xEE660F64267811F5,0x0A2C586C1BDA9B03,0x7D3F2C6E82861304,0xA14A685BAF4498B7,0xD8CEC90C63AB0523,0x44BAA252236A59F6,0xA744DCC5E03875CC,0x6C641C2EE472D1AF,0xD3FB78C1345E864E,0x9E69754CFB90A1EF,0x4B97E49BDAEAC09D,0x1C0438941AF8E148,0xFBCCC490D7A495C2,0xB0C49A542A2A6EA2,0x73EAA512D0410B7C,0x9EB433AA5AF1C901,0x97CC2A28A9C37529,0x8A0E1FC5F86C803D,0x915AA730D584DA1C,0xE341FBCC13C037FC,0x4A757382A2CB8E29,0xF9C4462A651F3ADA,0xCB8707ED642AD0B0,0x07D1A87ED699A8B0,0x9311CE0A8D0F5BA6,0xE05FEE28A5DDB1AE,0xF280E18B6A2E26D4,0x7BD0E8EC44540148,0x0347DAF018AB8E3B,0x7ACDFFEC9773CA5D,0x1360E41766699050,0x0DDD501BC26F2C3E,0x9F879E8A46FE85A1,0x19B41CFD7B8A2F92,0x323829597B978CBC,0x482BA57575BED7D1,0x9D094D1A2CB78FED,0x7CB480810692D51F,0x5A2F4071CB7C97C9,0xBCAE5F49F401D2B6,0xC666BCB885DA6DED,0x601E8112D19A53D3,0x4947CABD754C3DF7,0xC9D1B1CE9D3F0B14,0xB709C0B85EEA189F,0xCF628BEC40691F40,0x3B393A6EB81A2FA7,0x6508CB3760E7D670,0xC3295F1E5586D41F,0xD53F4A8D672A1FD3,0x0CD702A73A043510,0xE9FC70CDDFD68FCA,0xA26FDD32CB7A6E41,0xC1291AF5EF446F26,0xAA35A91C062DAB45,0x06C8B321DD3564E1,0xFB28E6B7A5D92DC8,0xA5E4BDC2438385D4,0xE06E3B452F31434A,0x946256399284AE2B,0x905CFE7E7143FA43,0x70CBEF2EDFC078C0,0x8B47257052A0321F,0x34007CCD444E4764,0xFAF64AF818832C52,0xF5A4B6E4F77709B7,0xA8C3888465E6DF2F,0x20D00D5D1602C226,0x24D03145622C579C,0x2A1F53B0BA1148C2,0xA4ABFD20BF567421,0xA03672F5B585252B,0xF77CC30541807CC0,0xC3F4F2A0374A8997,0xF177D0C7014B1E18,0x21BE6C1F79B50F7C,0x0B82CFDD42A1512D,0xD214DCC13250DDEC,0x2DC71E1A2E9A88DE,0x47E459FE437B6F34,0x74C63CADB2C3EE72,0x474C80CCA50DE91C,0x18B0B11720CBF236,0x1A76E3C5F11F0B8A,0xB1FA80DD4E58F0D5,0xC2F84DD0977C29ED,0x0194F4B4D6ABE237,0xED63924883DF7271,0x47762005E57A3E0A,0xC20CFD807272C5CC,0x66E5347EF35892C4,0xE5C4F65EED0B22E3,0xC432CB764FEC1641,0x73224A8D0E0D88EE,0x0E1653F426EB94B5,0x898F058F0607E261,0x19D4A88791182539,0xE3AE383FF1AC8EC9,0xA33825557A0330CB,0xD49FFE006046ACB6,0x1FBB338DA91AD8C8,0x87E7AB9BCA698785,0x1304A317662BEA64,0x9426EE5655B7D471,0x9ADF92AF436CA943,0xE4E7D5C09942EC32,0x5405B000780EF048,0xCE293CE94AEEA3DA,0xF58391BACB0E8CE6,0xB88FAA247E0045D8,0xB1C5B0F578F5D7A6,0xF029E5B04D54EA05,0xEBAE9C2D4CB8097D,0x947E1A30ED2422D4,0x1C5BBB6B7BE482ED,0xA6A74742B4C4FBBA,0x80F499ABA81A0C5C,0x6B3B03FFB85D8109,0x0C337E98A8904694,0x0838F86F24553FF5,0x7DB7C39BEA4649C7,0x615B77B66262ABD2,0x17523126063949F7,0x99BF30F3424B27F4,0xF4B7A2703A8B52E8,0x42A7A2FF03B10ED9,0xF8902B3729612DD7,0x28AA19184A7A4BDD,0x7CD7539436BC36EF,0xF452C605DFC75000,0xBCE37CA804913E8B,0xBBB627EE1502CB31,0x9A476877BEEFBA07,0x431700EFEE01CF4E,0x4327F2B5320177CD,0x13AE7FEA3402EF21,0xD518E01D3497E0FF,0xF248CBAB2A42D958,0x5AA9DBFAE0B597D1,0xF29D8D17169C9F45,0x1441BD87824BC6EE,0x1DDC07ECBE53B238,0xEE264CDB40F9FAB6,0x41FD9EE992A2EDEA,0xAF034FC275A2B6F2,0x6C2703E109B47561,0x2977C1BA4B231AAF,0x05D3E8E65DF2384A,0x7074D94686153E1D,0x18DB31D7E54BF520,0xD2F0C88EBB9FFC2A,0x3BC7CE21EDD42EFB,0xE00230012CC99756,0x043A85C01C4281B7,0x5217E2B0C30C4E5E,0x210DCA49EC3C1CE0,0x13A17169DFE16FFE,0xA893A6552B1FD0E0,0x93BD75EBAD156877,0x4E2A3485CE4538C0,0xF6301A2012408285,0x8F56BE5F581EAE1E,0x488EF3056AFAABB8,0xC50245D1CF5C2723,0xB9A11023D08E7569,0x9317D5B04523C648,0xF472AD4DA4C2BE22,0xFB440827B85CB8BF,0xDB175A847280AF2D,0x60D6BBCEFFCA6CA3,0xD47ED0B3486A00A1,0xFAAD2FDCA5653229,0x8714C691DDF3D549,0x186D25E8AA2B7D5C,0x48EC440C1DA43D14,0xDECCCB753F17EC2D,0x3376E2928224BAB5,0xA98DECCEFFD89697,0xEB5EA5A8CFF3A3F6,0xA0BFCDCC1E2E7DEA,0x7EE7E517DE0BAA61,0xEACA5C0D6FD9C184,0xC39C07FFC86CC908,0x69426A1869189FC3,0xDD4D8C52768F477E,0x45085B5C765EBC12,0xC7BC5AA618C8515B,0x231AD3661D4AA253,0x2031BFF36F9E5856,0xC222DC453B7F9F2F,0x8D9F6360716162B4,0xB1AAB6D04BFD345E,0x2B26B0BD4E624F36,0x8DC377A128A343B5,0x0C11592CE17E8D7C,0xE1D26DDCB2C37B53,0x592C97169E29633F,0xFEA6261A2003E372,0xB7A7CDDB8115BCC1,0x8192F7B860D3446C,0xD4FD41BDE90435A8,0xFC94CA63B507F5B9,0x592B7ADBF93759CF,0x2A76545C15D51C29,0xF7F788E6FFB0684D,0x9EEE6609B1B40EE6,0xD1F23299C9B8A7E2,0x4D36A65B99E92421,0xCB55A36EF5DC61EE,0xAA097600F09ECB31,0x6901D99A1B5743AC,0xDEBB5B8E30002086,0x185CD9C419FE67D7,0xD0F12B110B36F0F0,0x56E5C10A5B8495F2,0x77F641749068BA71,0x3D608CEDB22A56EC,0xE167F331695556B6,0x67E941259662CC1B,0x868A4B9B0F570323,0xE8FE5C191D951B6D,0x82AC8EACF89B3C00,0x3BEAED8AB9751BBB,0xFA7E94DED494ADDC,0xE04AB71B4FF09283,0x5B394CD825DE7DD6,0x5A2502753ADF4855,0xA8CBEA1309A28FCD,0xD558987D3FFBF1DF,0x7167541B8581D372,0xE11B1154CF1DA3A9,0xDAD0CF468EA8C392,0x42BF17DB235E2447,0xBA8BB515F86186DF,0x254AB6CC57A7A9FB,0xA9EC7D25A46E4ADD,0xC575E7C36F4DF85A,0xB44548822FCD03EB,0x57D0E0D5ADC96387,0xCDFE82000830D823,0xF8010E08B92412F2,0x2085ED773330677F,0xB1FE247768691ECB,0x30A55EF6AF674346,0x156B53127F1CECE6,0x2DB9903DFAE7D4CC,0x67D15F0C3C180413,0x34E693C8AC4D2939,0x01ECC4F7EB552720,0x7F09C21DE58A1723,0xA075BD895EDAD079,0x69D1D95084046343,0x162495F08254AD88,0x689349337416F8D6,0x16FB33B8259E71CA,0xCDBCC66362D6A575,0x42927AFE93EC819D,0x6A684DAA5791F8D1,0x2857A52C04368793,0x1AF153B75F079509,0x36775AE529606346,0x4E138EA9F28C55DD,0x734C419C172C729D,0xC48BD8A9466DBF79,0x5CBC8D6AFC4AC188,0x3EBB21DA8933F546,0x1221FF2D27D46765,0x9E980179C2E89C3A,0x28D9A30AA535EFD1,0x730DAB1D3185806B,0x1B86D32A8F1C44C0,0x5CAA81BAF435BE29,0xA7392E9768763F55,0x4B7176CA566E184C,0x1B2D542B6ED5B715,0x44B43D4A3322945B,0xE5596DFDB5BAAE0C,0x0ECDA46BEC2E4F8C,0x84F4B77E765253B5,0x129D851ABB2F0795,0x427FEDC163F6DBA6,0xEE512A280E9EAEFD,0x2DFD1DBA44660F63,0x027C1C35ADB5F80C,0xEE09843F9CC38098,0x0800E3B8D1CAEF47,0x7B99D3D58B6F4559,0x02F5CD229A6D4333,0xCA096D88EB155885,0xA4CB14CD3BBF47F5,0x5010D859812DD0AC,0xF620A2A8114041D8,0xF69F56101A17658B,0x20F65591443D43D3,0x03A1DB220EA52449,0xAF6455E7DDB1158E,0x222F09DDF0A19F0D,0x5F2A969F8590F3B5,0xF33AFCCBEA30B90B,0x7178C31B0EC0B81B,0x769CCA80441510FB,0x1CD36B7EE93BCFA1,0x0A6FF5F79A537D95,0x081D8E5D3DAD8510,0xF51DE441BE09CEEC,0xCAD9725507D2CC81,0xD04F44BC35978259,0x7F61D7FEE8FA410A,0xDFE4065C0609BDD1,0x32D910F01ED5C4FA,0x766D483374B2ED34,0x2E96171A348730DD,0x2B405A857D965328,0xE6E859D4C93CF243,0xFE3AE06B54CAA6F5,0xFCADF9FE36ACEC28,0x6C870CDB0261D725,0xB2780BCF402EA8EF,0xB2D7BBE2B106C3D7,0x5B1A42422FB24542,0x0FBCEA068B6F665F,0x260BFAD713C6107C,0x0CFA37DABBA42504,0x864ED92AE28621B5,0xF7EA5A7BDA8D064F,0x2436C830F2596350,0xBB39D685321AF01E,0x75A67BB3F69A5800,0xD8E2900477B066A9,0xDFE6DD625AB4DC22,0x6BF99511D6C92203,0x9F4014DC2B3F39E8,0x815281DB74A818B2,0x9E480DBE374DD91D,0xF1314F992B18EB0D,0xE3C3C81E21B46673,0x6023A7D5AC519156,0x71ED9E00C553AC40,0x9005C19B3B94EAB2,0x49ACD5884C91A02C,0xC35D9FEABA113127,0x3EBF4DDD26994028,0x2CED44B01DE309C9,0x1CA3C614C9F70EE5,0xBFC138AF2E56C5D0,0xBE4D9C728C08C967,0xE2C411B64FF641CE,0xFBEB7373F08846A2,0xCA116436851C4941,0xC6F8CA7375542209,0xCDABA4252FA5CCA3,0x3CF04126608A3440,0x852E1B3D4E4EE630,0x9AA3D65FB286CC91,0x3E179741D2A549AC,0x711643218A88A6C7,0xFAE2EE3A5A630544,0x76408ED7C687CBE1,0xAAE02A3C5528F867,0xE69B5CD60415F200,0x6A953B3AE1975757,0xD3322480D1480423,0x06664C58A305CEF3,0x0ABB18B3CF0F9ADC,0x07320FF15C2E5CC6,0x02738693E823FE02,0x4671A26E65E18E86,0x8187C0E4B36C6635,0xE0AC99902BABCEFF,0xD8352D4535DC1B09,0x8EA9F6739B4E4288,0xA314FF528CB4170F,0xD761DDDBB32ACE0F,0x79F7D15BC088E3CE,0x6DE3BE99F6DF7569,0x56CF411C219C4B59,0xA2F8607FD88D91EC,0x73D528E728667CC7,0xDFE396ABEB91FED2,0xEA07B279B80191CB,0x040EC4A387276342,0x7DDE72A0432E3CA2,0xB174B01EC15D7963,0xCB46F9299DC51399,0x77373A5A6238C070,0xB1B55E2F04E9C11B,0xB74D501D28C35C61,0x7CE2F454704605FF,0xCDF75BA00AC5A147,0x9CEE63754AFBA042,0xCFA2A74717EFF36E,0x266A260209B33367,0xC0EB05FC3540DE2B,0x8198D535466EF57E,0x772420B6D76FB14D,0xA634911466A3909A,0x0723FA011598DD31,0xEFCCA28711C518DE,0x5A4D9F9D4C408C9F,0xB482060D0A7A383F,0x1CC7D2C57E12125A,0x630938A093AEA32E,0xE7B54DB57D3204DF,0x3ADC93965272A785,0x95BD4809618CB27D,0xE21F51DB38145C2A,0x1FD9C364CD8C2B8C,0xA4FE3936B211CC1B,0x630BE3AE55BB100B,0x5790570BBDA43480,0x4598D1C7B88D314C,0xD0FC38732B09F237,0x8EE967CA5351F524,0x6A70547B12A512D2,0x542ECEA1EACF9C13,0x9886B69FCA607F87,0xEA844D2A8BDF778A,0x52AAA4654E4481E4,0xC4E3732673B85F77,0xA4E8709C753B8FA4,0x7B5B7586DE2B7313,0xF532F42B2F50357A,0x7B8F7EEED45E2D06,0xD0E6400C1D6DE768,0xC13A57B6ED9568DF,0x6E7B4DB249FB320A,0x68382D2AE82EC13A,0xAD6DCF488FB773F9,0x41BF47F791888107,0x68B360670587054E,0xE70E7DCD6F051299,0x8A8AE5287D904833,0x2E9139A666B3522B,0x2461EA491FA6A944,0xADD2A92D3BCD7D75,0x635F986643421AB4,0xAA32E1C61CCF85C1,0xD7CA46D329DE9DFF,0x1B9E5A55E941A529,0xD4A5BAE3F1E0B7D4,0x102271123F031553,0x0B97078C8F5247A3,0xFA885A6EF0A19446,0x544A18517B12525B,0x617961390999DA72,0x6701F9E2F65D0C2A,0x5EF6BAC1332D2C0D,0x0BB7AEFE4D983A64,0x6B698D52AF35A2E8,0x33F3759DEA926341,0x00CCDAFDBE83B47B,0x36FA697AD39672BB,0xB900124EE21028FE,0xAC162CB80BAC33A2,0x18DB05CA7922ED70,0x97B891A5833C726A,0xB8BF7E64E6CDDABD,0x76854B5F16AC4CD9,0xF9A6D32FD2BBBF11,0x784FBD1C32DFF5DF,0xE8093DAF2EAF30A7,0x324ACB58041DA014,0x88E93C8E7817F2FE,0xBFE2A18496C69B3A,0xC7CD070E80D6CFC6,0xE04E2DFD59930FA4,0x65F9E3AA292F92BC,0x4135676CB1643DA3,0xAA99E231C71D7661,0x06C7CBEC308E1F0A,0xBA80AA310BB58BA7,0x261B68A52D0E6B74,0x16C48B843D28F223,0x5EE6384F57CFABEF,0xE6384423B96791CF,0xC9C543FDA1D4011B,0xB85CE9016D8F5BA3,0x99B6A87DFAB674D6,0x4A32BB2E93ECC0FC,0xFD29D55FF8039848,0xAEBAF0D00A8D5CA2,0x68CB714D186E4B0E,0xEF474C774B81F120,0xA929946DA9EC490E,0x17E6F4F46148DEC0,0x9B93A1732446BF5C,0x9EE1760C8551B4EC,0xCA40DB73188042F8,0xBD7BFF1FAE643FA5,0x35A821430255E334,0x157E76D9A23D7965,0x06F6F8301EB232BE,0x5F45C55E63CDC1A2,0xA974474F6B36C55B,0x375B44B0551CC253,0x70CF833E54E0F161,0x378248584974B92A,0xAABBDCDDEF1799C3,0xAD7161C5AC12CCC4,0x48BC233F60BAB705,0x16F14179938BAD24,0x33F2372D3A098A4A,0x9EB4F70F907CAD58,0xDA060D7CDCAA7D79,0x8F69583E9DA1FC70,0x3A96AC1922BB4D93,0x7BFA04DDA22E1FD9,0xCC25A6167BD479C2,0xD28A12E99531C9D1,0x85DB1DEC9B7FE2D4,0x7F49241A8F107CA4,0x9E5A3B7DD9890619,0x9B9CE49D1D6DE6CE,0x6F35490B6AE5B360,0x90AA097D19E9252D,0xCE76CBD56DB30D3D,0x61DEA39B23904DAB,0x2C09044C7DA7AA8F,0x62A8E1C4C056957B,0x3A312BBB6594DF3F,0x683A0F18F010F69B,0xEC2B10FBB3F31B14,0x47F963D1772E69BF,0x0EC2F81A5779961E,0x172EF0122F42EF4F,0x2C0EC5333C3F8247,0x4D548FB5D809E94F,0x7C2A79D6F8B332C0,0x9019EDF9F5BEEA7E,0xA4EDDF850771932D,0xB8578D92A6C57929,0xCE684CF9EFCB40C2,0x54E9BCB941548854,0xDB1D015FAFFAB160,0x927FF115C8E6D32F,0xE9DB1BAA04533D9A,0x0815C69BA530BF2E,0x2E600D2043B77082,0xD119638917FBE1CE,0x6E311A4BC88AE8B4,0x743F8D2327982EEE,0x6B4F9BF51A7E39A9,0xBEA7D89CC9E29400,0xA4B2B5546786CB9B,0xAF8F3D3C94F744EB,0xCBDFDE1694F5348B,0x0096F0553E408D93,0x13A4BE6C54EE81DE,0x6A28AF6A2AFB4F10,0x00D7EA396DBF51FA,0xA828A3E0691AD5C0,0x16EA095FA66ED459,0x1B1C8BD0705F2CB1,0x1E970D5156145E06,0x3AB9D93C9615BA74,0xD42833F9753FEDCA,0x422164920CCCA1A3,0x2E8252A00347E830,0x6EB9BB8707BF6D12,0x7E7E5BAE17880341,0x5FEB8D90FC4829A7,0x51ADFF3AEA529688,0x41947BB43ACADFB2,0x166B850B19686AF1,0x513639B76F155AE7,0xB9DD5B019CAB210C,0xE748FFCCA64C8030,0xF93D8EDC42C97578,0x1D1DAB488CCD3639,0xD3B0A5ABAFF377CD,0xE319BB7F852301B0,0x98D2CAF444841C4C,0xFFD635CE3F114FF7,0xC261D9513544F7A0,0xD3EC310239567480,0xC2F75A9858328B88,0xC21A8832B3E05D59,0xECAEA6D76C5CB6AC,0x1D936E5730B081C8,0x51B78B1A85F5E5B9,0xFA18143D2F41CEDA,0xFA0C5F61225992EC,0xF6AA73CC9D8D4921,0xC40538C1C7AB3C20,0xA7247679CE7A2389,0x7303F5879E6A0820,0x3AA77B5D0145607C,0xCFE70018AF1BE838,0xB96A3CF18940DEDC,0x29C3401F4CD3B892,0xDCBBFCB45381BD94,0xD8F7CCBFDEA10FAD,0x100B9D3AD9E181EB,0xC67EF438E267FCE7,0x2444450CA75D8EBF,0xDEBC24B8CCF06276,0x0F51D94514EDA34B,0x7F374FEB421CFF39,0xE40588A5CB25F415,0x0A881DB93EA4B040,0x117AE960DC3FAAE2,0xCE440A2995C1D28A,0xC40BCC1192862782,0x5F3628DD1134F223,0x9BD6015DEA9682FB,0xC6C1101320888FBE,0x22C3C5DFFCD6AC68,0x176F5A5D3530F4F1,0xECB3663BD2F64C1D,0x90CBF9503A82308D,0xC63A917D6B8A623F,0x4D9D237F21E2C1F9,0xD6AA4F61AD6E3AD0,0xC2FFD6AF8B749744,0x870E89C8C14B1F91,0x82E39809ED6375E9,0xAA8D5AF967BB2A24,0xADEAC775340D1745,0xC3C53BDC4B5E66E2,0x776FA728991FCA1F,0x5F205A6FC9FDEB8B,0x500FB1DD4E5BFFA6,0x8404A913B998FCBD,0xFC47B799AFCDE204,0xCB71E64E1A417CA3,0x83F9D15A1CA7DE3E,0x83985B74CFE93AD7,0xEA8CCAC66736EF93,0xF32CDC2D94B81DC9,0xBE678408EE26227B,0x81ACF1EE59935CE5,0xFA3ACE94615B4E3A,0xBDE2296FACA567DE,0xE88EFBF324C06F2A,0xEBEE3E48EB0C4577,0x197B4416B1B3E3D0,0x28C146D7C34B7D07,0x3C4CD12F0225B31F,0xA13AA05A8C842BDC,0xA6E964E8D1AEB690,0xC8F78EDD1FD22E60,0xC3BC42FE7399F98F,0x6DE6C72094407D00,0x9A6EFDBE55A31C5F,0x89DC5196D8CA40D1,0x156A3000357F80A0,0x1DCF39B5E183A0C6,0xD1E9E4BCED3AC0E2,0xB28DFFA778AF8CE3,0x29226D14E39BAF79,0x60BE1C41183879A3,0x0FBCFFF7FF2A90E9,0xE186BF08585E22BB,0xA674D9C05A68C7EF,0xA3C3F93E391CFFD3,0x9AE8022CEC8F28FF,0xF96D19D59373397C,0x422A0C850462A611,0x7FED65B4B7FE4D54,0xCB3F5CE5D2356249,0x3CDC165F478934D9,0x10471976219CED66,0x26282AAD44ECEA46,0x5FCDD7E0C30A0AB8,0xFFB3491663708969,0xD499D81534928004,0x62FE2754FD9CAD55,0xE5A3ED2DCD08AF27,0x204284CFF08CFFE7,0x460995B691461FC8,0xEE0A27E7AAF6C3EF,0xF1559EE438CF5308,0x231770B3878A7D19,0xB1403BFFDF8D1EF6,0x3F15FC596A7D4E15,0x7F5021F7A7336DE0,0x4A8935E7477CD3F3,0x92F4D0292DC7627D,0x19F6B50EF5779124,0xB19B5961F1705CB1,0x18DF6B612D6FE078,0xE73A065C0EF1982E,0xD76B3B0725477866,0x2FF4094EF58276AC,0xAC7AAC4B95F0CF52,0xFAF68D5806729FB1,0xBD43CC6699AEDE2B,0xB952BC663F31282B,0x29B4F5F08BB66A07,0x0B41DD904ED0C3FA,0x413FE8B620BCC097,0x473B4010EEB40B5B,0x3CD358F21B2CC2C7,0x49E2B45EC47AA885,0x2EA7FE8C1DF854DD,0x8E70862F08885AF3,0x7AC807BE5E905685,0xC638552D50AD449D,0x4AAF6E9BD321F50B,0x617294225401525B,0xD446CBBEF8D08F15,0xD9C5DD84FD30B2D1,0x33455DF8B3A1CCE6,0xDC9E15AAB48C1267,0x3911D648F5D11539,0x7504067A7F92B769,0x3620E145DEED1FA8,0x6AC075328061E40F,0xF23670BDE92C3170,0x94B8B2DD3628CAB6,0x8742AF8A844A1601,0xCB408685B94FC478,0x730C22506088DFF6,0x8CDB576177ED6260,0x33275CEF999D635D,0x41974EDF9CB16611,0x74ECF32D5D345E3F,0x2F96B364B6A377D9,0x27605A10A82CA44E,0x2DFDCD715A03D9AC,0x8D5CE30A1DDCAF81,0x54CB4D0CCC9F80F5,0x168E527EAEFC6040,0x5A4C56224FDC91C8,0x71A59BBC22109B93,0x16C0C4166995CDEA,0x540CD14E1BD0DAD1,0x90455E436EF360C6,0xE553059F09059493,0xE5BD2368FCA09219,0x0D0172C5F6BD5EBB,0x9435A446885C1CC4,0x12CF52C01F29EE60,0x7C8B7717694A2E33,0x4F7AE80198831B7A,0x46022804DC144E83,0xA554DF774261970B,0x28784590FD73DC0A,0x33E3951016F05269,0xA520D7D6B045F35F,0x40637A37A810087D,0xBE0B8A5999CDA88A,0xF2C4F6256D170561,0xB8FB52BD1727A853,0xB8F64039AD522409,0xC0A8AA4341EC9065,0xB067893BED654ACA,0x68AB65AE17D40FE2,0xD6B539F445606641,0x8E5DAABEEC4E357A,0xB865AB717E08546C,0x8B79652F1E01041A,0x8C2BF3FFD44909DE,0x4AC7259FBE5443AB,0x186A3273D6A3EC42,0x99CB81D6F80E229B,0x1F2863D01D7F78E7,0xC31087617B589887,0xB9C2E888950D66BC,0xEF0824F5CDB94E13,0xF1E12BF851DBDBF7,0x9E8CB9C0D958D16E,0xB9873F1907E4DC11,0x4F17B7EA9C76F04E,0xBC5C7CC9D9829777,0xC99AE4D87DA6F1FE,0x6B003516736B622A,0x058A0715FD241135,0xD0FB5836F6D51C0C,0xC24DAA5C8BCA17DE,0x7F59D219A6D4BD3C,0xFABC8BE752B9BC65,0x7FF39C04857701F7,0xAC3107DD6EE8D7EA,0xF523557E798B20E0,0x0C9B8ACE0C32E5C9,0xA3221C2DEB616FB6,0x925F4ECE60AA6924,0x9016065573B20BD9,0x8D8370FF3ECA49E0,0x931C206FAFBC3DD0,0xD1334ED6B303BA2B,0x4923D2B851625D64,0xCE61279807587A87,0xB19AE80191A04231,0x783951E7D891F9C5,0x6C58B66A52BE29A8,0xA22AC558E1363465,0xC19111D771C5F79A,0x343C3287CB0742E0,0x61DF57349A564856,0x56858DC9BD124DCE,0x846C88525F0FDC2D,0xAF38BE1A5254A1F3,0x62FA7E8F3CA8B0FA,0x203F472AC24CFABA,0x92A89C4B359DB130,0x590F71BDBA8A8E24,0xD0646FAB75E230C6,0x3393149941DED4A4,0xCCDD1368A1EFE5F1,0x5300A9440D421EAE,0x24153A29C8E27920,0x76855B2E0925F4F3,0x685A0E393A685723,0x2B6061AC99F4BD7C,0xC577667D08E2147F,0x469158026F00A0D8,0x6510E3EC924E3B0D,0x6E7066B13AACF2AA,0x917C5300FAC27E96,0x05EA20CDA1DF58A6,0x74556E6C2B2D7D17,0xFFD3B392714D89FF,0x0A3B33A6BF986EC0,0x17E80774F0B88C47,0x8D89E13F99AC8422,0xE88C2913A6304563,0xF89B9094794645B2,0x22BFFF3EC1D6A8C4,0x18FD001C0A4486DA,0x9E672E00443BB1B0,0x7CEC8503D7AA3618,0xA9805C4D5593222B,0xF476E65DCFE1D1D4,0xDBD4F4AC4428CA27,0x28ABF5E7E6E5E049,0x9127549300225DAC,0xEA9C5A09E4A60AF7,0x40E8BB50EADCD0FE,0x1286E8F3E530B077,0xBFDC37E08CE1A10F,0xB3972A0F9E22C0ED,0x444395AE0D9EE819,0x4F6E3128A2A09725,0x2A0BB72E79C72316,0x05C974D4C375AD89,0x46E121A8FB90A97F,0xB6DC1E3A07C5A517,0x24E7646AE4EC9E50,0x457DA4CBA7F8E56F,0xD9EA2274023AA8A3,0x31BF8A859C7E8495,0x7330A24E8D0C6771,0x28A9D5865B3B648C,0x436233B505F078A8,0xF126FD80804FACA8,0xD38E5A4EAB04EB48,0x37636A696EDF77A7,0x58566475B4AFD338,0xFEA3AA7050B70A71,0x7D3AFA67B52B6920,0x90FBC8674D77C124,0xEFE0CA31AA20DEAF,0xFB4A8FB936687424,0x30DE8ED7CD6C8F58,0xC2185C060089A670,0x5212188803A0F7B2,0xD95183A15B7AC9A8,0x0FD8ED5D4CDE75CE,0xE753F535B48D129B,0x36EC1AC8244C7DF8,0xBEB63A19860FF802,0x30DA4A2A285A471A,0xEAA00BA5CF009342,0x6F65B61867801B28,0x54A62B6C1236BC72,0x7E5C029155FF0DC2,0xAAC552BAB2F317DC,0x03FD790C7175543E,0x257228FC4B6EA5D7,0x71581F714D794CB5,0x7547564B733132D9,0xFE513ABF3B60F9CD,0x9C84C9F1B1D5C2CB,0xCA5A02DF9C4D7C3B,0x15F8FD966992AF83,0x084F405F676B6946,0x820ECC62A7BE9ACE,0xD5EE8482F46D6F64,0x5A73918E8353B473,0xF4110D00D59C8EC0,0xAB8C55A1C2D53B83,0x34E0CE29A1FA73B8,0xB4CE449056D5CC22,0x437BF4598432960E,0x1807DBFF1689B1EB,0xF690F11A74476673,0x8660DA4941929535,0xC3C8A3713330F0B5,0x5A1D6C6A7CB90A69,0x7D4258F4FFFF5FF7,0xBB2B2C607802E155,0xFBBDEF7403A558BA,0xD866A8CE0D9C93BA,0x292743E3F8B51EB1,0xBF208A1478CFCC5C,0x6557D486A37A4B4A,0xB4A71DC8FE4FB228,0xF92A2BB2E155D5FB,0xD1977BB2A7B58025,0x9641AB88D6C9C96B,0xD9881EA745A148D2,0x6ACA86A348606403,0x3487DC8F665730D7,0xC19C56F7F19FBDCC,0xC0771638FE1AC5E2,0xCC657BAD8EE379BF,0x9D0047384AF7DDB4,0x8EFFF1329C95AD1B,0x2110BA4683C84758,0xB01269149B521291,0x8AD81781B9089C86,0x67EFD9DD24E5FC20,0x63BF97FB2093E15A,0x22BFCE08E6C0E1FD,0xF878FFB54F8F55B1,0x2637C98455723404,0xE0C3F1AADC840D2B,0xD899B7B78E323CB5,0x25924A8666DF32A3,0xBA0C3806EE9F4D82,0x53A7568F372D9E5E,0xA9B059E0E6B1CA22,0xABD58442C34F4BC3,0xA6B06049BAE99AFF,0xDC69F2AD77CD5D92,0x0482F9889A5CC54C,0x38A67B9FCD167634,0x6EF7E5F8FCB92AD4,0xA0CBED90F6B798E0,0xE42F64101B59F858,0x55A6E11834DACC9B,0xBAB3DAAF784932CD,0xBC2579F64B234899,0x8FC604AC03E6FDDB,0x47AAC7D3C494ACF4,0xE76676E349A4359C,0xB4781ED9643FF14E,0x21003568672F9953,0x79126672A1CEB14B,0xA0318330B1B28E10,0x7AEE2A9E23DF940A,0x7B7B408164DD0C3D,0x8D012997039A1426,0xC66F212DBA625167,0x80665C5DDE72A448,0x51C423C5A4718C30,0x4EFECFE2E0D63D93,0x798CEA1B46216373,0xDA32D7DD4BE3CDC7,0xD4DBCA2F50CCF437,0x150ABB5945996539,0x6C9FB652075D891C,0x9BEDE80A87F65305,0xC83C73DD9FBD1B33,0xDCB3E39870535A8A,0x2B0BEC209A8A5703,0x4D3B49915E27AE0E,0x2103FBEEDFB6A725,0x0A1F5641102BFF09,0x0125405D6E8ED98D,0x2FDAEE78EC4C7B05,0x1FB515BAB0DB927F,0x1A2239DEF8A49773,0xBA40024F22DCCBD6,0x99BA35D0DD30235B,0x534E3018C3B7F906,0x1905C2768FC23880,0x67A7828E366BFE23,0xE0E4BD17F34CD48B,0xE37BD9DCE8A2409C,0x0144209F06ECF163,0xD785C4C70E98C80B,0x245B8050D235E858,0x8985A01B8C903067,0x0A4090437F65AA63,0x3379C2501C8E7028,0x32D07F104E4F26C6,0xF78E07DA9DDB81EE,0x1F4E78D6E58640E9,0x4B144D03EDF71E12,0xD49F637729B1B48C,0xABCDBA2DAEA49236,0xA11214A745AECE77,0x5CC8F05F42CDD3E9,0x2CF5673698FEBB44,0x8F6D394E1C8A5233,0x9DB4E73F616BA5DE,0x09C386E6822B4E51,0x24E8396755D7C8F7,0x2549320AB1E14FC3,0xBDCC1177BFE6EFE5,0xCF1C74C904E1BAE3,0xC562AC65ED029BC7,0xE9A86CE2C4703D99,0x343F5D89AD92A6E0,0xE1189560616F440A,0x6ADF3AF9B824864D,0xC0F16AA789D60CD2,0x859B7F3BD4D32827,0x2C757215ADCEE9CB,0x8A999DF74302F385,0xFC161C813B48DCD2,0xE1379D7F0AADEC55,0xA59E4552104AEDD6,0xC31BE2CFCDF311E1,0xB11816514A420C98,0x83B87E067F2C7FFE,0x87725044240EA2AA,0x7E0CF25D462536EA,0xD56DFCD22590926D,0x17D7256D93994058,0xDB508F430AC9D82D,0x21C7A4E7F221A9D3,0x13AA22F75F3A9244,0xEF01EA25679B07E8,0xD59A6A658976E40D,0x5FC4AB545518796E,0x2E58623AB855137C,0x52BD5A7C297D2A0C,0xCEFB3FAA5BBAB7D1,0x7DCD2557036117C7,0x1F890D12E57CD65E,0x5139CF4C6B11B5D7,0x824A29749E2675E0,0xD5ECD5D7CE2914B5,0x6DBE7D40681EC878,0x9E6EB5E04BB5BC3D,0xC7FBBAD1CAC9287F,0x14B41DFA2A30A22C,0xE7A038C9C2AEC6DD,0x845AC808829887F9,0x27C0E371A6C08AEA,0x3F618181EA5DBAE3,0x4B7CB26ED5862C1C,0xAAF205B009DC0B1C,0x44B0F6B9B726EC8F,0x477EE2991AA61CFE,0x96DA7347034B2FBE,0xE6E121B2084E6CF8,0x18A52816B046071F,0x15C95062F31A76B8,0x6CF6926B0F6BD245,0x93B03E1E127B7301,0xEFB0585FECFC303B,0x1495C9332129C023,0xBAD7F495D2E47633,0xF5DC009D4A5569D5,0x8115DF49EA768787,0xF25218BE876E0FFF,0x5CD5530ABA711DA3,0x1BEA68AB7DD4BA75,0x36C86B189DF6ADF3,0x048E1C7DDF93DEC7,0x569C3CF955E02A9E,0xF25E61C30D255446,0xC1BD93BCF2253B87,0xFF2467C107B01988,0xD7509546406294E5,0x09A06BF0F2DE35BE,0x3DF2F7A6B04C5B4F,0x350A578B0A2AB538,0x6748B1B9C4CF4EF1,0xED958C9CDD315730,0x337BC48F5F75B118,0x576F4EB7BFA02934,0x6A33379DB79E9721,0x0F3235CB1614D83C,0x57B537582D161660,0x574D71E00A52B0D8,0xAB3DD990E6EEFC1C,0xCD75CF7A743D6A40,0x560A4C6061BFFDD4,0xF93C4695BD2F881F,0x64598407F5F72FD9,0x8AF8DC3D704E1595,0x131D3C9081976422,0x2580EECDF1FF8E9B,0x4CFFCE0C0698E4CD,0x46371EA567FDB682,0xCAFADDD14AB82F6A,0x7C28582EAA18F874,0x749C717477428359,0x06C7C85D3C0601F2,0x6F970ED69D58252B,0x476A029A545E7259,0x6851461826F05A86,0x58B397B51224274E,0x085C86F0A1180714,0x1BFDF2E0AAEB994C,0x6C8B07A89489EE46,0x1ACDDEF7D05C6204,0xC4724D955DD90888,0x5FE09BDA5FD4196E,0x33DFE7521E4A9F8F,0xC70732BC0CF14CAF,0x360D508788060ECE,0x2C47C8059E3156EC,0xE22DAAADD08CDF6B,0x01E48F51ADE8A9DC,0x6F0048F314C914F1,0xF5E542717647AD03,0x3A90B2368D0A6ADA,0xEFB835E98621D53C,0xE1C06FE9DF3076F4,0x9873AA0B91D06594,0xB4D4381506114A94,0xDAFD6BB89FACE66D,0xE68C1EA2E72A6C78,0x1D7775CA77248B98,0xA9604A069D462DFF,0xBD14B84D970787B5,0xE26FABAF2461DFBF,0x17C633A7D31F2FA8,0x0F8477DEB6149A6C,0xE3A8AEE593CDF1D3,0x01E2FFBDCBB1D33F,0x711DE666E4150E7E,0x24A3A7DD008B3687,0xCED4E84521B9D773,0x3EDB3F32852002DF,0x593E8F15073FD6AD,0x241B92AFCAC92FED,0x81AAE3EAF48DC12E,0x49772B54A33D8B45,0xF3FE0F9D608843B2,0xE06A5ADA4E53F10E,0x132157515706EC6C,0xBA43BC65A16A6F24,0x7A1F90E7A8A8DC85,0x932036BD40BC870B,0x5512112EAA962BCA,0x07731E4AC16AD367,0xBC34ABE274EED3BE,0x726088D10DDE6076,0x0E4B98D6B6B32FE0,0xC5B1FD747BF9CEA1,0xB4FE22FCD7726F62,0x76723EBFCF3B6875,0x12B59BE2ADDF1681,0x9D2F250ADE2513D6,0x5AE6A2E8395E9C77,0x7D6F5538AFFB62FC,0xA8EC2CCBA13BDE46,0x2CAA899A80E7EAA3,0xC5995AADF3640914,0x63239BAE3549526F,0x5162F3842F040134,0x93857EB63217115A,0xE8BB5AE4DBB5570E,0x20ADAD233FB112EC,0x994B92CC45CC9797,0x496E2F2359992015,0xA7AE141E9D685083,0x075FCD646161485A,0xE0001F4D92899A9F,0x683E48B669078180,0x5B0BFABA405BA06C,0x0C5AD5176C9AA835,0x4C689A91566989C5,0x67D6A8D57DEB13E3,0xB8637A92CB91E6FD,0xE349B4C60521E90B,0x28EA426769D8B3BA,0xD01B71204EAB2F09,0xCAF76038090BBC67,0xDF36A78DD8F3FD97,0x1210F583AD9C6E42,0x7EAD21776ADED751,0xF742A0629F2003AD,0x015492C6443F4290,0xD0BEF64F677E90DA,0xFDA749C6701DBF1B,0x7EF529E3D4FF1A3A,0x83FA31BC5849A7C3,0x23335BE54725BC2D,0xDD5EFDCB56AE5F4F,0x218562B6D2DB25E2,0x29806C97F1C1C53C,0xCC2D2938F6A47385,0xBC46DBD06B613B31,0x37ED2D83CB3AB162,0x0BBAA34A523FA769,0xFA5BC14F2AA05F01,0xC7732299EF4D7D41,0x3E47B37B8A407273,0x9B131ACE38A119CD,0xA7DA3F969D16DB4B,0x1B627CA0101468CE,0x9275A05FA40470E3,0x92FA4C0646B03D12,0x23C992D3549C1FEA,0xEC44106701DC9ECF,0x7FB326ACC692D3D0,0x491101FB62B65416,0xD9B43E15617B3268,0x945BF84DF9892675,0xC0933BA403F172B1,0x4C10F6F7BDEE7C86,0xB1ECF8E7722382BF,0xD8FF855DE82D3255,0xF9506020F9EC0B14,0xC4B538C84E921DA0,0x8B9F497CED00D174,0xD8DB25264E7B2411,0xFE901DEA8012825A,0xE7AB7C230B7C8E71,0x1B6E46060F855CF5,0x5D1FCC457CFD3706,0xAEECC5DC173ABC8B,0xC6C3DABB767FECF0,0x16380ADB4CE88ED4,0xEBB2F967B8C81727,0xF79F8AF093FA6ED3,0xD30A7334E390AAC9,0xD274A2C1F3E6DB61,0x155BA7ECE155AFE9,0x2C1FCA5AEFC00A39,0x1E57ABDDBFA33180,0xB5F86DDF5635B40C,0xA4E21C2F5AB01D45,0xF2102B54FD8B857A,0xD93A23FBD6A2A4A5,0xAEC26687236119E6,0x82B96ED879C0DD87,0x38BF90073FBE8E08,0xFBFD3D99325E6835,0xDA5C7E79B8814B43,0x7579C8DB665FDE4E}; +__attribute__((section(".data"))) sh_uint64 test_search[10000]={0x4F05B4544BC5E942,0x0AAAC9555C732EB4,0xD23B91640B7353BD,0x98D11B64FE9D755A,0x465E61167B4AF385,0x50A68A70CE222087,0xE75D6E6D5DBDCA3A,0x2C276C4A4B1A9F6D,0x6B7A427570044215,0xFB5EF826D3DFAE0D,0x7EA5F626F3D032F9,0x4308274211873307,0x18C291C47D17CEC4,0xD0D11778EF3855F9,0xDC5A5664EAE57904,0x8CB0BA05A262DE29,0xC2509A8E5052B5E6,0x055FC40EBFE73891,0x282C92AE668DF0C2,0x05717DC500933224,0xCC3E49168A7B7879,0x58CF465D00ABD0F5,0x884B7D93746E0061,0x0F8BCE46D59F8138,0xA40807DB8C5B38DD,0x567A5DB2E5A97555,0xBEC6538AE3777050,0xA24B7866612ED3CE,0x44BEE3A6BAE53367,0x511B3E5454CD8586,0xBF9E045071CD747A,0xD0CC8109699E7A90,0x0AF6DD17E7805250,0x763B28B47085305B,0x0A5E7546D5BA5477,0xF696931479F78493,0xC87DE95812250772,0x8063BBD2BC9C3C9E,0x0CA8BB3E1D843AA4,0x89E1E842295DF2D6,0xDA1AB1C868E762D2,0x61D8E56DC482373B,0x12D05CBFB56BDA0C,0x8FD4167E104BA5C2,0x86455B29F11B6D45,0x13D3530B1F817B60,0xBB18261A3D225384,0x69ED8C9D053BA1D2,0xBE50FEE3233AB9F8,0x9C50BACF1DA9D67B,0x893F11927376374B,0xDFA42E62D51F1629,0x0932AC0240E1C423,0x5E4DF2C9D9DA0146,0x6D5792D7A60D68C2,0xE72CBF917D6E6060,0x7DF386D360F5BCA8,0xD1BB9D4F975D9B4A,0xE90AFEFD7D504628,0x9D02CD903EFDBC73,0xAA4622F9732AD5EA,0x561655FFF45C49F2,0xD1A6155D0D3EB26A,0x80A3A7F6DAEEB380,0xBAA8F31403856DA0,0x34E192F7DFC4599C,0x4DA75007CB68A746,0xADE8D9F537C65F1C,0x232F19635060684C,0xFBEF445086216382,0xC35A7BFF1741CF48,0x3C95275AF859DEED,0x173E391829D2B941,0x3A7A63665E10375D,0x0FDE167495769446,0xFD6C11B55E53CAD0,0xE5BA019F7850841B,0x98A44D5BA0FDB928,0x84FAF01D2B3909B5,0x70826A995C1CC172,0x7401CDEFEE17FBC9,0x396250FDD32C1DF5,0x488D9722D8E40A80,0x32A968DD06DD7A15,0x304E91DB81AAC612,0x13015B723CA51664,0xD126957CD34B387A,0x6B9DEE02E7FB3967,0xA850F00E66CEC93E,0xF238E5367221FAB1,0xD47DDD505E5CA97B,0x467C126325F9016D,0x19E0FBA952EF0CC5,0x40B3464FEF2B5FCD,0xC66288FE95A79527,0x949A2642E3ABE4DF,0x25434F03BE189412,0xEBABBD6302ED44D0,0xB836845CD03188BD,0x8B9517D61061438F,0x9D1B02B58FE741C4,0xCA1E31298861BEE7,0x17A6C0BA33E4F5D3,0x7B4BE7FD9461A310,0x1D27E84151E3E1E6,0xB8262851446E77CD,0x81BA6701F4426EF4,0xE5E032CD1AB7A997,0xC3F6E583467711BD,0x8A825DE947B0DF6E,0xD1593B67229EA71C,0xD385066C79B98C47,0xF1AD161AB600EAAD,0x8AC36EE1AFF41BA3,0xEFDED6711DECFC80,0x5FBE9FE746E9B458,0x104CE3E737118433,0xCD233D6887279137,0x37FBD94478C31D88,0x4316016B01380B78,0xCCAAB74FC8345AD9,0x56E29F166C817876,0xC92B34F2F857248E,0xBE209CBDF9E9156C,0xECBDBD9ED11E0296,0x853DDBE0E3969A99,0x6419C35DE54D1951,0x68E94D90397781A8,0x24C98E7684CA2781,0xCE5095A2256DE184,0x551EDD678B7A4F13,0xDBE2E2D93ACDB3DD,0xCBB81EB24093B267,0xE0FC0BAC80110A5A,0xFE45487124433942,0xA7C95D69CFD387BF,0xAE806CF9C0AE8CAE,0xE09D4FDE84FB0C17,0x4C367F419E28CD02,0x042F18A7CF21945D,0x61B3824CAD04665F,0x70B539F50E9F80DD,0x86D6FEC04B09CA47,0xD54B6CCF7F2353D1,0xD3D1CC0D336BC8D2,0x74FB2D053F6C214F,0x8A3D641F57A23CAA,0xBCF82B1D619A6B69,0xB7BEBFD76AEE331C,0x02CE59A471E20792,0x824A793365D2D5E1,0x0CB8C1516097E52B,0x970B2E950A9BBAE8,0xE11DEDCF1E20A44D,0x1D6EF6AF2B626638,0xB2313E3398ACDA6E,0xE7886B8AFA296C39,0x4856537A0EED1B20,0x63AF9B0225181CC2,0x308F7F148FC1C371,0x68E95873BEBE23E1,0xC6FDFE8B3FF8706B,0x527775146B44C7CA,0x842D24039CEBA7B8,0xAF375BEBE4326E4C,0xA3662FA4672F6226,0xE06F8402C950D330,0x4361174C8D43FC63,0x4FDFAC8051D4F175,0xFC1FFEF88E6EB029,0x1A90ADE088400DB2,0x34D7EDEC35433F06,0x1478E94526F970CD,0x36EFECBA0FDFD11C,0xAFE04973EC080EF5,0x408134727D1A374C,0xCF492E873713A4D9,0xF8E2A5BB27B38553,0xF98A06185FCB2CE7,0xFE8A8FA1687E82FF,0xFEF4A6A20294FAE4,0x9C365C487DC228EF,0x5529E8E3D199621F,0x32040461C19B7B19,0xC8BEC976FEEEEE59,0x14133DC88AB4FB30,0xA052D0A5E05CDBE9,0xFB583A53599E100D,0xBB0CF222ED0B7A19,0x8DDE9AC1763A6670,0xA8338ACC3DA647C8,0x5231BE4770ECB3B0,0xF169E5E04909368C,0xC8D75EE2A07DA68D,0xA6F3D8F1102DD3B5,0xDE31ED7FFAACBE95,0x629AF8E5CE490409,0x83FE85366FC5C6B0,0xDBE3AF5B62425C80,0x6BFE643C147F4D7A,0x79C40A0358FDD01F,0x3EDDCA0BF70A9872,0xBD4CB2B53213FF3B,0x811254D1D0C25A34,0x9C75204F32DAEDDD,0x9B7FF45C8BA143AD,0x070D8BBD1F4DB902,0xD32D4E7E96A9F8A6,0x4075FF81A34D4AF3,0x42A8A9D0C391E8FF,0xFC50378B703BAA12,0x91EB30CF168375B1,0x7E9363E14EC3E778,0x09E423224E26ADBF,0x64E91E9BC8201921,0xF2A99DAA17D39F77,0x1F57954FB57DDCAE,0x2DBA519C2F1B900D,0x8D2635A2421F3190,0x4AC2B9E14E198551,0x7D0F89597E109632,0xCF1FA73FE56E5703,0x6B3733EF144E23AF,0xC2C9AA2533D56B56,0x899FFA669E46F9DD,0xA078B32AF7669534,0xB9708974DD91C39E,0xF24F5F7B46585D77,0x0F7C215D86D71847,0xF46BB59DADFF3F92,0x9E9E0FB9378C3734,0xE35516631C2A4DD7,0xBA1AB175F5407566,0x849CDB58D29E2C2D,0xD728D62F545891C6,0x631532CCBDDF3A4F,0xF20CE9783309D668,0x19F973673904100F,0x376188518DE9FA79,0x2076607C63280EB1,0x12EEB861C0F68619,0xB35E22F5AEA631C7,0x24029B8E819837E7,0xB4A9A50547FCE40B,0xD8FD2C626D50592F,0x27BCD17E16660058,0x2713EE07A6C41A05,0x4242CF585DD03CEB,0xC8AF931374E871CB,0x42CD204BD7D1BBBE,0xBBE94C057DFACF36,0x9690ED254A34E5A7,0x54391EEE7C93E3B5,0x7B47F29499396B79,0x691234A6BFF4B047,0xC82BE0663052675E,0xBB6F2226B4BBF86F,0xDCF118C68930837A,0x1D8BD8D1AC58D652,0x9617288422260041,0x1D13C5C334F5C678,0xB2EBFC116E1DE9C0,0x5F7C2F8AA78FDC1A,0x930EEFD35F4386EB,0xFDADF371D53E2696,0xDC427C7F507AB311,0x5257D87A0A4D9310,0xF8B140A3FE62CF1F,0xE7046FA77E558F3E,0xFB7E0560CE4E6A0C,0xA4CE45119B489F98,0x3033D4DB6BAAEC7C,0xBBD01AC6C7C08D09,0x470785D55CD249D3,0xD17DCBA531A0786F,0xEC94D75AF47765E8,0xCAFF26F255F84DDD,0x880808E66B35B139,0xA0E1E74D776B1DDE,0xA9ABF092F9F5C0D2,0x6BA16A7FA886D010,0xDF5D68A65BDA041E,0x1A75A4D2C54D0A38,0xBA180A0DE4B3C356,0x7AC3A306C4FD0B6F,0xAEE4AB26B6F1FB46,0x47213E27AE6F59A7,0xA5306A910A2E426A,0x2F9300F03DC1F5CD,0x3019D0F9A58A6C15,0xF77EF3847B823CD9,0x4CC28FFD9E88A80B,0x276133BB23B83553,0x53CB31DE07943369,0x63EC200A8FBD3087,0xF09B3B65F00173C5,0x18BEB330009AC3A1,0x40FCF301727F9835,0x9592F37054BB3F3B,0xF01C6B9EE2586933,0xEC19547F16DA5835,0x62BB167EBF2CDD75,0x4E937B2D22BFDCB3,0x9C8B387BD22A8DA8,0x8B16DE69EFA704B9,0xEB4BBF3F01934BC8,0xF072288B79513E43,0xF767DDB33336AEF7,0x42E90966ECE2227D,0x0B8751E66252098D,0x8DCFBFABB69396CC,0x741B3298D7CF7797,0xAD77B7F173454428,0x250FEC312CBEC42C,0xDC6E1A5146B0EAF1,0xA213C3B1D6AD245C,0xFA35A8DC45D87F6C,0xDF56E2B0FD8B1395,0xFEB08484921E47E3,0xB6B8DF8B1C8A81B3,0xBA107E0C3A357A7C,0xACEDD464E450FB53,0xB8A0362B49F59D58,0x51F9249F52F6AA45,0x629A7EED9E668599,0x272E9AEEC5DD1BC0,0x6CEFC339C596C228,0x166A762030054775,0x62719E426379F057,0x2920280EE7D6B242,0x9A398E2E7FC3CAC5,0x2E5EE2FA64366A7D,0x254C4CC6E277349B,0x34FCBE1EE6142759,0x5630BE037887A3C4,0xB9BA7C3DA311F834,0xCB63A48D4D275C6A,0xD3A68E623A510383,0x1A058CF67002AB2D,0x8B3551635BE7F623,0xE68E0A8C018807BE,0x70EF93D3343586C0,0x18C696854167B84E,0x76481545EA8626F3,0x02AC948E6E28BAAC,0x6B0188B5D70736E8,0x19A961F8BCA2917B,0x9FD4166A0B0A84D1,0xE9C6FA4000F2D5C0,0x2971EF44EA361C5B,0xC9AC0FDF678CA909,0xCDEA30B165023EBE,0x6705596A39C55633,0x97DDFC22D8B497AC,0x8A03CC2027840A29,0xE7859AF4BD82749C,0x93B9DBC3704DC67A,0xA387E7C4BFD8FA49,0x7C9295E79533B1C2,0x6F00F4AD81939982,0xBDDF7ADDE205A881,0x90756B402A5307A3,0x284B71DF99900946,0xCD1F39D314008CA5,0xB642EC2976C20471,0x1B29DBB22A70B796,0xCEE7ECAD26653474,0x793E921C8BCE5B23,0xBEDDC4B4A1BD37AF,0x4B897872E7E6B787,0x81448D7E1E4DE43F,0x39A87F4E48CDC16E,0xDB0808A66CC9F4B1,0xCA6266E2B6A634A5,0x4A1D1AFD1CA0B884,0x52C4866D88FC3F8C,0x67041C75CFCEC559,0xB91B9F8018C1E0EC,0x1CFCCD5945C1C0C1,0x10C908E590B39A4E,0x5CFF2EA40BA357A8,0x18196B37A2487CC2,0x542FBB119522A284,0x9CAFD0024969438F,0xD7EAB990D6F85466,0xAFB79C4F51969250,0x4604FEDC662CB4D0,0x38AACD4B83154F8C,0x368015EB8F062A99,0xBAD6AFDB76705402,0xE958029B17D3CED5,0xA0608077CA84DA67,0xA9ECCEDFB5679DEE,0x0B0257A3D26A76C1,0x905B000EB3325ABC,0xFFEAF60D72C1267F,0xDDE25D8B9F820DBC,0xC3467FC76F7E5A97,0xFFEB4EB1E083087B,0xACEA45F55CFF16A1,0xE6EFFECBEC87BD1C,0xCCEC8FBB5778F450,0x00108F5943BDCC07,0xC10DA7C6450E3741,0xF11E0D851B337E50,0x04FB9530A0D90F39,0xCD6057E4338BF325,0xA567103B69C13D9B,0xB14ECC8281DCDCA3,0xB259028BEBFA5AD4,0x00CAA5CD2A256AD4,0x0FDCEF5206BF8753,0x42DD870AFFCDE726,0xB99DC310F86924CE,0x727B2457B986B051,0x91958B96CBDF6377,0x40F4574F830E6E27,0x59B2B8A0AA00059A,0xF456E02C6B189617,0x4B3B9AC356ADB2DF,0xC2DC040A8727E79C,0x8FE20755DCE25C38,0x6D0F61345AEDA086,0x20CCFDF3F6B49A5D,0x60E97DE15F15AFB6,0x10186DDAC1FACC2D,0xF46648C862552401,0xC9A863AC765292AF,0xC14299AC0945935B,0xAC6D3DE63E624CB0,0x25F5CB7CDA94BA26,0x342D433E7C3C79EF,0x6122165679876614,0x78E5A09C20DA5398,0x058AC05C695F4A46,0xCC61754D7CA6F35D,0x52C3C53D5F671A1D,0xC4D9A68CF29CE994,0x80D3314F39151810,0xEAB128CDCAF74823,0xFD4462462C0CF554,0x9D457543FC33510E,0x9CDA4AB96F45D50F,0x8FD88CA5341A4C90,0x04008C1AC0C2C458,0x85AB06C278A63791,0x036DC228E9642642,0xD2C852625B4A7552,0x6740B0EAED1BAD30,0xB769603FB0B8633E,0xB4EC0E5ED04532FC,0x3286D8A2FC933B69,0x1C43CB76CF7E3940,0xC88943CC7C53CC7E,0xA03D6607EBA7B991,0x9ECCE1E548336068,0x0B3504D52D682562,0x2A40F204DE9F338A,0xDC7844C5D497C921,0x02D9384A020E1B95,0x253FFAF9B0A15D44,0x53C0A4D2D2DBEE40,0x7AA5E00D41BE4D9E,0x67C0D79D4F3EB21E,0x0084A2C271CA36DE,0x74FFE169487E13FA,0x87F02F79DB155C20,0xAF21798F8945C52F,0x5A610CD1D27B4965,0x4ABEF808D40B3EBA,0x464B03F251D226E2,0xE94E834E3F47F6A0,0x1A83FA4C0A044EC7,0x0EB0C7E2D756A9D0,0xE2F4CF654ECAA9E4,0xA36A910895830EA7,0xCC429F0FE2B247FB,0x100BE18A2C0784C7,0xC7A7FF62A3CABF7C,0xA5187752F7544AC8,0x36B9D8297FA3BFF7,0x92211291D97F3868,0xECC306CE03CA6094,0x8EE368A17FF5193D,0x3A0452C033098A61,0x8A40B50BF68B8AD7,0xAE18BC44B929E508,0x12F28ED510CB645D,0xB0CA8AE9DD45A4AA,0x715CE8E542E0E3F5,0x28A8600ADC501E4C,0xEBD69944E1618E33,0xF75F78ED820C0175,0x8C1353F5A662D647,0x7C09324ADF1173B9,0xFFE7E5B2CF828BD4,0x62D395BEFDFE1F79,0xEF3624AF5A87CA2A,0x773076076C9D4E5C,0x6AF25F09DD2BFEC0,0x9E002D524EDEFF62,0x3E859E3C925C4D64,0xF6D04DCE56372B58,0xB3224ABD9670A541,0x113102B2C2A67759,0x62BE7152D1351E0B,0xA6F7BFF24BBAD30A,0x89252F6A4B20EA7B,0x9A22D05B91B955D7,0xDD7EE724F379A257,0xA6EAC81B00932B5D,0x454BAD8C22EA75B0,0x39EE8586D99CAADC,0x61E2CC7165B10166,0x2C4FE1D2B939D251,0x6323B4102F1FC5E4,0x95BD384BA2F17F63,0xC49B3C25C72F77A6,0xC9A3116D600D8E1C,0x679FE1A7F972EB17,0x4103532FFFD379E2,0xE81E4AD947B3969D,0xB54EEF17B7CB4B4C,0x36F0FFCE972A972D,0x01CC0D4E0F48F022,0xB3FA60C15C2BDFF0,0x4A166D299328CD01,0x44D8DDDCCB538A58,0xEA47B71F4A3333DD,0x5C2447A35CC33EE2,0x4853495168EE6065,0x48F4CD588B6301FB,0x2F8338D76A6B2A43,0x81A00A9B02D207AE,0xB6E5D043EC6BE83E,0x6DF6CB46B9966017,0xEBF4BFC0A88BD168,0xBA3EFC1E2ACFD712,0x2785E2A4522E0713,0x6308A9DD77F35600,0xD1A7D550EAD17769,0xA5F15CAE159F9E0B,0xE1A5D77EFF817989,0x19EE8975509C2125,0x4837B006370267D9,0xA115183B4584AEA2,0xB2F458F52D53B77C,0x6CEE2BA39B0C265B,0x835251CF05EEE3D7,0xBA568FACE5150A1E,0xF7BC1BA277C6DA06,0x83E0E7E71CBB0B8A,0xF13137FF791F3E68,0x19520493EE128ABD,0xAC8036B445A3D420,0x7994EA437C579F21,0x2558F63F83CD829C,0x1FA421497332C335,0xA3BEE0ACC4A41468,0x36B2AE358CC5AC17,0x5B1D5FD96F4AD441,0xDB259559CCA1D292,0x41DA55D692177DAA,0x519443BF2DD5E8DF,0x1947A507991DD898,0x4EA5F625E9EF46EF,0xF63EE5FFE5FED930,0x25EE7163830329C7,0x1536121635CECADE,0xBAF38B179B8A1AB8,0x4D73DEAD0AA22DCB,0xD135E6A75A6578CF,0x8AC42FFB4CA14C54,0xE4C9C2CFBF689D25,0x451FB3E08AD225C7,0x0CBB118BD83D4A5E,0x11C03D0F1A6AC9FB,0xC832A29661171D1B,0x8CC1F29836629355,0x85E2BCBA7FDEAFFD,0xB62BA2D330DE5CAE,0x54E6A547B1067DBA,0x62F0E43A29912876,0x56C51EA944D4108A,0xA45EE64252C58A86,0x447E5230FD012701,0x2D43B0187B32F8D4,0x98BC3D7BB91517FB,0x50B082B5A3083DC0,0xFB60B0F59CA0FA95,0x84BA3CF6EA57A7A0,0x7314A65E2549828B,0x199CB9DD91195A75,0xA277835C2056520F,0xE2926F65694A3B7A,0xC589070A00C07E64,0x7F5842004E706A5D,0xC1C89A5F770FC3A0,0x2DD0A2267A338F1F,0x97223C3705F2ED03,0x0AD81A710B2089A3,0xD18720613E979AD3,0xD9D0C7C56F5CAA7C,0xB515D1A51EBFA6F3,0x359794280430BA31,0x5D12B90D7021F1E2,0x3E4BB79A7164686A,0xF5B865403AEA1656,0xC6E375DD03B6CCC0,0xD391887D36276789,0x9EB723C5A81FA9D8,0xB4871F2D2BE46A46,0x97A90C1377CB01EC,0x8FD2F87EF0A76FDE,0xB3C480A69A2E9470,0x1123E563369DFF4D,0x7E94A2AD2C835B9F,0x3287B9A6F85AD6A5,0xA4249D210849646D,0xC13195FCBFC21E30,0x3E55F7BDC47B8835,0x7B5C31B7667F9E0F,0x57349B0A703A6E12,0x58773C998EFEEB24,0x0D2C194EAD670264,0x563A6A611ED964F6,0x6245B12481313039,0x171C80A9DD2926CE,0x3F4F9D91C078E228,0xE9051A93B55CEDFD,0x2E2B3111CBDF16D0,0xBB83EF34419542B9,0x148A4FE7D78B7974,0x05068D58612C4C3B,0xEBAD3C6A1BB7E648,0x6A9F172FB375DDBE,0xC5ED48E4EFFDE05F,0xE3ADF7E506F66AD5,0x2791AB9CEB9C6B59,0xAF097CF7D5F64394,0x1BECAF974A62E591,0x9F119783F53DB720,0xCC6CE6843721C8DB,0x704E4BE3881C2193,0x6BDFFF03612F13AF,0x329ADD9828D31F0C,0x49176613D1615516,0xFFE21C4607C78E9E,0xC033D97DC3FF2775,0x38F9188FB592753C,0x315AF15B7AC9C65C,0x8558C82F3D164B3F,0x26AA577BEFAD33CC,0xE926AC97C8195404,0x111B44269EDF3DF6,0x317E0E6221EFA81F,0x23828CEC7CD70FCD,0x2F7603AA13BF98E5,0x66E422C460E29C61,0x8E17E02105260904,0x79749B54AA3973AA,0xEE939B695B5D74C7,0x43FA30D742E775D7,0x37FE05C45159860E,0xF4321FEEF5896E1E,0xF2B2AE328C1D0C6F,0xCBBF90952BFE6965,0x4095DAC07FEE4684,0x3B83AE9FCE98EAB0,0x7E40B648DE18B322,0x21E894DA577D1E38,0x91306F167EC909E5,0xCCC8C281195F009A,0x7A9290055B0C5F84,0x411505EEAA8F7B94,0x8D0B5B17FC3CAA08,0x7415163DB03C59A0,0x1F118ED91FFE304B,0xADD1AAFC5117500B,0x68AB23F548E9B42E,0xD4622EF8BA64E3CC,0xBDD5C0647B800240,0x591B0EEC1D56E161,0x708D5EC978C86BB8,0x90FA03777E8247D1,0xDE4C0515D89627D7,0xC06C644A430583A5,0xBD0FA65D9741C3B5,0x3CEFE26BE86EFA90,0xF9318B0C3619F0E0,0x78E3A1E2942D620A,0x78A015FFC31ADAFA,0x96D47510CACD1692,0xA7ECAF55A4F77479,0xB0A35E6309913222,0x4308DFDFF00B5C0D,0x9EE1D198819C6459,0x134C7AC3CE4E42CB,0x1AA312CF06ED3AEB,0x031ADCE1DF50E8D1,0x4228B38E31AE526A,0xDFB885A5FBAC91D9,0xBF1469D648122AE9,0x077659573C228402,0x7AAD0D171600D800,0x525B3743079C9E41,0x6ED27746809F479F,0xB13BE05D89C266B8,0x48444533EBE8051A,0x57E300862FD99E44,0xAE11B776E8C5DCF7,0x4CEF8AADF0A959B4,0xF6A6EF957A207DA5,0x1A50C020F2A38FF6,0xDE94427F267861CA,0xCA30DA96B47251B6,0x579F5FFD51D072E8,0x331A0A272FD15225,0x152D7C7A665D89D3,0x33726B9D9AD916EB,0xFABC363673D7B999,0x43B389E968BF98FA,0x3B4AADEF1A62C2E4,0xD33ACA3FBBD2C3FE,0x173CCE5CA099A7B2,0xF9D47949F0A8991C,0x3538DE831A094054,0x07C7FF3384B68012,0xEE702F2276CAB7D5,0x103EE5E4F4533350,0x201B20F8F3D0F427,0xE90FC0E608B3FAEF,0x1F8152FC59AEC2A1,0xE1E4E5235C79EC33,0x88075FA6BA84E41E,0x285246BA1FE4BCAF,0x46618DCBEB00D2BB,0xB9FE605BDA799817,0xD9C228E6B82B419E,0x3B2E331FB15184F3,0xD157618DC3DBAF00,0x84332498F11D53A7,0x199F17CDDFA37AF9,0x629563011B71AB15,0xAC243606F0D804A6,0x9709339781ADEBBE,0x45AE33E4F313D6D9,0x1AB8015835A5910A,0xD403017C1C1FC64A,0xC9F9F08ACFFC6653,0x309C9574F1F6B4B1,0xE5A8E8856725A189,0x7813585E6C8ED0F5,0xF5FD6FA28B9EE444,0xA6CFA332584B2828,0xD3C859422A016813,0x410006064A085136,0x2175079077EF617C,0x92BD9BB893209490,0x4A2A850B37D5D0AC,0xFF99B76971163570,0xFB5BEE9EDFE38D46,0x75797D083489271B,0x0D0FCF3CB409F230,0x246334E6709EFB59,0x76F20F709C155954,0xE6DF1BD426067037,0xA52FA8027894FDD2,0x6630AA1AC8E56ED6,0xA74FC7C4FC0A91E7,0xE725E1AB2B79FC5C,0xA88960E61B0FD66A,0x362DAEE4E71D7FEF,0xCD50EE705C908425,0xFED7EB858F25CEB3,0x554A22EA75B74CA5,0xBB5E2A12CF73D43F,0x72FAF492CD7A12FD,0xBE7FE4138BB64BFF,0x60F80AE6039173F8,0x9DE55313765848C2,0xD86E1D4E96141CBD,0xE6CF5E7133DC4711,0x4376BB21F3EED11B,0xF53AEED2E3395F71,0x7B45CE93C9C52F10,0x457D045FD1EF57D9,0x98180E18B67A1907,0xCF45F74E40F9D23E,0x7FD7D421A00C1716,0x18755538FB1F6202,0x8DA26D5291C8228B,0xF8BE66768BE547A9,0x33A8568ADE7A34EE,0x6933E8122A63BC6E,0x9106E22611A86D8A,0x1DFFB266B534F8F2,0x6F6C29A2013E7590,0xB725ACA455DD975A,0x36CFA1D78164A2C5,0x763C810E05042FA5,0x6CBF1820920E0B41,0xA170DB4C19457ADD,0xFC7630C86E44E040,0x6C35CB043DBB1F25,0x3461F14125897411,0x60E123688A0A1B4D,0x46F39F8F5AD2EAA8,0x0C59D1171419A3F3,0xC01FD29DD8D9951D,0xE7BAD348599B2034,0x765DC30755FA530A,0x07CEF1F9099D5748,0x3261012F139C5372,0xBEDDB888EB20BE7A,0x332DA6A9C6118E91,0x949EB75A146574BE,0x5C115A2A08BACD54,0x13774A6F74D847A5,0xE86E2B647256490A,0x685DF0BAE9A5E882,0xF76169B17B54C0F0,0x5DCC472A737B1403,0x44B6BA617F5259A1,0xD7A1C227D8927002,0x5C296229A6C38E25,0xCD0DD1D649DDD4BD,0x318DC58B58A2FF6E,0xA6EC0AA77BA7865A,0xBE376ADE51777CC0,0x5B8E4D693AE53777,0x47AC2526E9DB54B6,0x89F40886BE3DAA98,0x4CE54DA14BEDDE98,0x0A5F84471132D7EB,0x688E65A5A362CD20,0xCC196719F953347A,0xB863FA090BF46245,0x4800A87D7B7E93A2,0x052FC77E33F43B25,0xF694735B6DF6E187,0x0FB9AC20464FA53D,0x32F14769F0C4B2BC,0xDBE2D2936ECA7AD3,0xF17A89496F30EE22,0xE369B34119D09B7B,0x3215A6CFAF8D7AF4,0xD832C87BD1610424,0x5D6210211ACF1CBF,0xE0D7C5AA1C341A79,0x7FE884375C4CF1AF,0xAD16BE670BC78F14,0xA7BF5135F080D97B,0x80DAB76B6EFCB104,0x4762C5AD041A0462,0x2A7A74234A6D61C3,0x1DFE97D98D9008E2,0xEC7AC98725523BB5,0xC61C26AA17A15F63,0xCF0B717B80A222C9,0xFC18AFA92CA4D025,0x61DAB3473F026ADB,0xF5DCF6C8625D7029,0xF196ED41B097A1B1,0x2E7D9CC7E5B54FB5,0x8C0A35E988D67A94,0xE855EB5926EE9A8C,0xA4B31C15F918F0EE,0x93083922ADF5A097,0xB8AE0AB07BDA00A1,0xBB0F1DB94D3910F9,0x6597436086EDC7E7,0x7062A1B33DEFF50F,0xEA2AFB35E3F0B7E3,0xE6868B94E7FEC63B,0xA56C3555CBF88234,0xD4519FF5218DBC20,0xD9F8FEA1EAA44895,0x300FE9D0EFA4B797,0xEEFE36DDD85E2AF8,0x8CDB663C22AEAEEB,0xE2773783F58575B0,0x34735864F669B13E,0x340F17C9A66EE9B5,0xBF9A8A9DA2AA1098,0xB0BB4F631A5CA8C9,0x55509E544AA2F332,0x110A411E734B1EAC,0x814B8805E809B827,0xCDCCA667B2B79DF0,0x33AA8FFC9E99E1F0,0xA707F3EE02053E43,0xF667A15EE6D4C3E7,0xFDC4D45F6A56BFF0,0x60942F051B7152E8,0x71CC4CF833720A57,0x41A0E2F90340D4C1,0x7D32C8F649CC8F37,0xE62957292A6B66B6,0xC9741573A30DDC14,0x7C8BB65B2BA7258A,0x84CCFA037BECA855,0x2BE7B2F94CD312A5,0x9E303ED52C569542,0x0B0535D35A485E63,0x9848B96375432476,0xA8B340549F129776,0x7EC2A263331AC4E9,0xC732B97DAA480A65,0xC6DDA2BAFA47653D,0x172753EDBBFA0B62,0x4866D8BD9D4B2CE6,0x4545226097472D83,0xBF2F482E739CECD0,0xEAECEC50954802E3,0xDB1983CCBA65B51F,0x2B6347139C5924A9,0x940212DFD4885163,0x4DB03EE68FA1F3FD,0xC7A21D0BD774FF04,0xB679AF6D140383FC,0x84A162AAE01771B6,0x71CEDB27C51395D9,0x545704412F4E44E2,0x1035EA345028D70B,0x7DE1BCFE2BBAE07B,0x18FD910B44AD09C5,0x946D69CE565864C0,0xEDAB7821A60022A7,0xE09F916908E6FCA5,0x6ACED6F146010645,0x5FA2FF68DC617B2F,0x4D96CF57EC17210C,0xADAE7FFD2E881B35,0xCF294D6BE1A4AC07,0x97E6FB30782CA3A6,0x9F43393584AB45E9,0x9C07DC25B96E8F82,0xAAD363766D2949C4,0x708E53A42009F8DE,0xE4E7C42BBE1F8937,0x029E3B1330B8BA1E,0x4B4B9FB1E26998A7,0xB8215A881775F524,0x33F5E574E7666D66,0x92B9F420B260B0DE,0xC90E4A60EFF16FA6,0x37D9BB45260BA560,0x9CE0D4CB065BC5AA,0xF8CEE2FB29CCF4CA,0xC79FB9D35D91E0E1,0xC377ECE541BDFB29,0x112BAA854A5DE0BB,0x846FA565CADE2271,0x3918B1EF7BB5A165,0x4C42B771D268F17A,0xE4CA177BAB6AF927,0x73D5CC44EF315C06,0x0886F9C642C25A92,0xB5D8688D0EA478C3,0x53E7E9D9642278E0,0x4E60B73194443881,0xC416CAF0B6D250A5,0x92233E0FA1842C6A,0x849D2992C6CC59B0,0xC6E141B240CFAD7D,0x1718BDA6F8625EFC,0x8BFCF3A1099656D5,0x790EA43914375168,0x74FBDBFF866F5728,0xC71944CFB005778C,0xDB79AE2A7327DAE3,0x9F2BB9C7FE682564,0xCA77FDB8BDAF01A8,0x2856352FEF8A8740,0x51777D529B5DF077,0x1D5E9DD567F0B777,0xB310B138DC7322CB,0xFBAF917093C68721,0x0D34F0817F136016,0xA1B1A1FCC7A5C568,0xF166DCAF6DF3B376,0x42A1C30B97C65E04,0x397BFE3CE193231D,0x29F24D27B5D51DCF,0xE027E174926B9077,0xBEA85FA11238D480,0x0BAB95C9F0264574,0x035426747C2A67C4,0x4683BBDA0EC8FF92,0x1A80BD4E8DC2CAB9,0xDE05740CB8064479,0xF95ED0946D0EF17E,0x296AD9CCA840B611,0xC5F1360DE4AADA07,0x373212F1B4C49719,0xF07A09D6A312EF76,0x43992350988ACDB0,0x00896D0A786233C8,0xD3CC1806364DECA1,0x4881324868A9124D,0x6F01C0DFE55B78D5,0xB86EF2560ECF2D92,0x787BBA7822E9C20F,0xF3F69FA55BFC4F47,0xB7AE5F41A4ED8B00,0xA77D6579D8848FBB,0x5F879F5BC22D1DA8,0x8BE2244FABDD514B,0xC6EFEBE7B8EE91BA,0x0EEDCC6407C2ED40,0x10790E2AA6B4FED4,0x611CB9D655C3546D,0x60D961B9179093D6,0xF6AA6780B12A471D,0x23E625044976FC92,0xF1B2B97825333D68,0xF377A52026FA57D8,0x7DD02B051E17BD0E,0xB65B21D906541A97,0x7647A6213EE2B498,0xBDEF7CA3346A1C24,0xE62CD0EF702C5F18,0x5E1C7F2A982D2CBA,0x9F378D0C7141A3D9,0xC6584E581BF0F207,0xD3837939A6D2C3AB,0x2C2280EA7821BBC2,0x8E3F649E32DA2A4E,0x791C9FEB9DAF5A7C,0xDADE757C90F4F477,0xE93E8B2563FE84D5,0x6E4BDA59A64F28FC,0x8A63A80D18605D8C,0x06507AD78B39EDB0,0x3581CC5F4D17BDB5,0x4502E07D0912597D,0x85E02057E058BA80,0x86D0076BB7A45537,0xAD04836837AD3BC1,0xE814C85BD604DEAB,0x2A97CE728F5701B3,0x3ACF13A3120EF27B,0x7420AA8EEE10012A,0x14F27669EBF3A213,0x2AE9FD13D17D80FD,0x1520DF42C5EA41E1,0xEED5F66DEC6B41E7,0x90FB2E40289FAF92,0x76134DEEBECB056A,0x99616FD65E6ECF19,0x34A495BCCAFD151D,0xC800D2CAE9B5ECC2,0xA3A1DD656F0F5783,0x15FB71932DFEC703,0xD2B233B91C9F1412,0x64EEF42A540BB480,0xEEC299A2E8D7707A,0x172C1625182F33EA,0xF453431159CC7659,0xFE0913807E1B327A,0xFA0E8A816472BB27,0x27DE3BC6B0816278,0x092BEAF408FCDA2E,0x008CBB58FD0ED446,0x3DACD1B2018491C2,0x826D6726542F9B74,0xCCE803D739106997,0x2FB5A80F6B201F40,0x118D37C8FD96C651,0x0348BE6BFB8C6AF3,0xE97823581A663E7A,0x9F66C2A59CF36C2F,0x33142AFCCF358C5C,0x0A64463867525433,0x32AA9DAD56329220,0xCC661C50B1FAEA5B,0x4E6104E4D5665EDA,0xE8FCFE1846332543,0xAE36677957820BBE,0x361CE4A7C4CE3950,0x068581B308F4E1E6,0xD9874ADD8D1A6900,0xB51B7DDE2B65CF61,0x3C3AF96784199A3F,0x54ABF15DFCF15EB6,0x69D0E70586DAAC44,0x3F7087B9CF913828,0x6C99F009763E6A56,0x7A37F0552E4BD87D,0x5A35DDEE6139B679,0x731BF508D9BA5156,0x1DC2ACA1AE7B0432,0x829995FF6EB63729,0x1416852FC68BD227,0x9495858DBA999E7E,0x9DC9F80AF641485F,0xE1C61A989F17427D,0xB08D64E229808B7D,0xABA946143CDF5DCC,0xF30DC2212AAE0CD1,0x20F7C95656BBCCA8,0x92CE847E3F02BAAE,0xB785086A913620F1,0x45FF927E493F0C1B,0x684FE65DD4BF375F,0x49C21F4492313434,0x23EF6A67DC3B2E41,0x53E8FB4F656789E0,0x0D48FAE55322F104,0xEF65D5CFAF91F68D,0x94FC8B693B14D4E6,0x9F2C20EF02B5184E,0x1AAFE73181990F8E,0x8FBA8264A2C4E081,0x9446317376BE1E7D,0xE27E57E0D0034430,0x099B772A99C319B1,0x1C4BC2C56C2BD6CB,0xF2DFF47A2D29B044,0x0C70CAF38ACA562F,0xCCD814BA2AAB4F00,0x4DC816037EE85E43,0x0E47D860772AF05C,0xA9C8868A073ECF5D,0x83C5168BEC499BAE,0x9133249A352238B2,0xF42AAC905951DF0A,0x9851816A2EC17DFD,0x192C1EE918B2275A,0x8559BDE0B980B955,0xFA7105646407051E,0xA81170811989693F,0xD5681750199EC54F,0x0F938C905ACBE709,0x0B4FA02464018A88,0xBEDA9F0DF85327F7,0xF07534CEE879890B,0xB1145170B0315FE4,0xA15E7D4969297912,0x6D24F528FD5E24F3,0xBCC2232BE08FAD4A,0x2289049BD5C3438C,0xD7CFC5911D4070C2,0x265C819D9BAD12A4,0x84A91BA572195E2A,0x1B4BF18B7A9785B4,0xE9F31E8DEEB365DF,0xB754D1E68F7ED575,0x2ACCBBA90C38FDD0,0x5FCBDAAB9F638131,0x74A523C24F8DAF63,0x1D922DA4D5C728D6,0x250FB99F6E5584D1,0x1DD6924F5C952E6A,0x04E9ED97B2B03C32,0xF7E9EA3CFB8E881B,0xB7910B8282B704EE,0xCF3E538A1111508A,0x5141C85BA4AF4D1A,0x53DDBB155FFCA952,0xA1228192B65D629F,0xB79ABB974423B326,0x921A517E37012947,0x7314F9E94F40C6D6,0x7637D64F19F5D05C,0x85E8050ADDDC3499,0xCFD146E6F2BFE63D,0xD989719B7E1DE984,0x808E418283298FCD,0xF8E29EE27DA15601,0x6577AFDF7312932B,0x7BC890E23357D624,0xC484290E04E0191E,0x7654E16C7392FAF8,0xB75FD7DB2360618C,0xDFF2F115DCA7A071,0x8F52C59676445B88,0xFE69FF2E73E5D4A6,0x8141B444D48DABEC,0xDDF909E54BB90A00,0xD3265CED704EABDB,0xE54CBC58DFFB3FD0,0x4BD9E1C47D8D5D08,0x7D117F9725E2E400,0xE77CD5106E378485,0xDF3A0C09344041A7,0xF85A56AB761604B8,0x7E9F1F47423ACEDF,0x999E4765CE0F5EF9,0xEEF10221AC0CC70E,0x926C4CB162944A5A,0x186B53219D951626,0x702E23ACDEDA7DF9,0xEB2878815A2F6020,0x01B1F2201C1846BB,0x50880E6BC3869AF7,0x5645805C2F2BA4DB,0x7CF98233F5322DDE,0x111D42035E7E1CC7,0x51BA1BC3F6CE199F,0x9324567F05BA864A,0x3FD7412A93F2BE4F,0x00DCB69F993F4ED7,0x2A26C29A50FE4B1E,0x7BAA2B44D5F7FA89,0x065AB9ECAA9F6977,0xD0D2EBF34636C423,0x05BF6C2F669A3766,0x2ED3BAB00016AC6C,0xC558F433534C6BAD,0xB0B8ADAD45DB6A0B,0xA14D3C38EC1AE0DC,0xB77E694044BFE96D,0x825603740979B58F,0x48D8CD0EA62A5098,0xFDA686049A7D2489,0x14F501B5A8E69BA3,0x35A7251E76455285,0xBEBAA0F1FD0AB1F9,0x6EFAE761C55545C3,0xE0F8C707FC25675D,0xD143EED3D1070AD9,0x39A10F730734F074,0x77461C921EF1A2AB,0xC999AA70FE521600,0xF2FEA778FEE27AD1,0x10F94A8EB74123C2,0x2EC7F614E0D43BAC,0x188563160310B17F,0x4D112508F5AC34AA,0xAFCCF190396C9168,0x1AE9C99ED225FBC9,0xF34297E8574CFF63,0xA44FD098CA95ACCF,0xECEAEFF6AC7574B8,0x037EB84B582CC8E9,0x7ACC315A2C50309E,0x8156B5B5C49ECD55,0x0FA69BE4114C16D7,0xB3A6F084CDC164D3,0x0CA4362642BCD316,0x6E6D72A9D934FC5E,0x314F18F420903242,0x18450736C33EC7B9,0xB49941FC45C7AB64,0xA43E4FB24C10FB62,0xD93B4EC5442D1758,0x16CC56CC9816DCF6,0xAC043EACDD86F84B,0xFD0E116C607F786A,0xAA3262BC8F6FF9F2,0x00A537AAFCC3C57B,0x981B5B9D88C6A914,0x8F1587E8994155A2,0x0A6E5F6D94D447C1,0x4E3D37256266D7FC,0xAC7104C9C966E89B,0x9DB9D5221D1CE637,0xD4CB75CFEF618D1D,0x9564D226A70D9B43,0x0559B029DB523CDC,0xD83F253F3FCDF85A,0x29AF3C27DE2F1584,0x9D3E5171F684EF38,0x1A91BF862AE4E9CD,0x37DB99AB150BACE8,0x8DBD1AFD00137B86,0x0084044F8A2D8DF2,0x4C5301C773D82C79,0x82FE043FDCA67854,0x106B87930501CD6C,0x2C839BCD25DE9CDC,0xD4EB045A4C2E539E,0x084E189C25933310,0x69DE4CCE24A780C2,0x3938BBCBC000CA7A,0x285F380A2665095F,0x360779F384973D2A,0x9270815B0F116C0A,0x25C764E797645A5D,0xD3886059A18E9B24,0x8E88322444D3EA25,0x0AAEC96DCED7C0F8,0x5E02AC8280CA8B22,0xCD143E2113F465DE,0x285D16B1F1A4348F,0xFC1DAC2F122E668B,0x9D19998D83F885EC,0x613DF0B96B16DE66,0x44415E7992443BEC,0xB10B56D8C22E81C7,0xE21D0B112DCE340D,0x91EE20D7A48138CB,0x886155E77BEB6F63,0x567B36371E878EFB,0x1C6C617ABC86D4CF,0x7043F09AD90A8E94,0xC538A6AF1D10BF60,0x4FFAA35B2CB06746,0x8351B72C87B09FB5,0xB41C60CD4646856C,0x6E33B4CE57C69938,0x11829D5CEE83C451,0x5F2E3960FAE22B36,0x22A9E0ADA3566AB7,0x27C82B4D3E7F1E45,0x46860224203DB384,0x6BEDBC1A5502FD6F,0xD39947BA02CC36D7,0xFF89067BDA4A2F01,0xCBB09D111ECBF3D3,0xC75C2B67BA6639ED,0x7144D9CC8E073958,0xC86DC51C320321AD,0x37D652DB3A742428,0xC3000BC38F0359E8,0x9F2A208D0AA3708B,0xD0A538BE6B497416,0xAF9CDDB1A292177B,0x9E207E17500036FB,0x0C7BA2C9C6B8F17D,0x036532452B425308,0xAAC40E849AD9C0C4,0xEBA8049FC866604B,0xECD4A5EBE4FEED6C,0x65DB0746E1210367,0xB4E0CC477A70B7E0,0x6EE6986B9473DB6A,0x468FE22D57517EFD,0x62AF1DA24869F213,0xDC6D2343C54CAD23,0x0FA9FA0B96E24083,0x1121A3854B5F3678,0xCDF051DFAE48B2AD,0x729D438A4181DCEA,0x6381633A64025B6A,0x36734A73D793003C,0xE261D6267016E0CA,0xB8A1D7C99BED480E,0xD7C5D3461BD46145,0xDD81017BC916EDB9,0x0327F90917487432,0xC87FB9F8E3435E3B,0xE77C9375AD614A6A,0xAAB52299186ABFBA,0x4E41C662EEF55E64,0xE7131F246CF8BED7,0x54856B717F966D5F,0xC65CBA555454ADB6,0x205B9EB8CD2AB729,0x8B6AD04FEAD770AF,0x9344926F37708980,0x2E5E358D369BA2D8,0x93C271098AABDCD6,0x559BD280238ED5C0,0x50D267C88E4F3EB4,0xD1FDE7F9CFBC558C,0x6A390E04C6749C22,0x5BFC3D88F31FBEA6,0x2C456478EC8F986B,0x7343D1D5B95FE865,0x50F783E7B125B82B,0xC00147206886B633,0x9BA3C263D4C3E157,0x3A9D114CC274C275,0x7548DCF303DE2A1F,0x29F048B17DA35498,0x8E7D09BD1896392C,0x0C58A2A307AC079C,0xDED1C02C4FA3F360,0xCF4350220D6D9080,0x812D5AC030D4B2D4,0x752076688B30EBED,0x3299E90DB3406458,0x951D47C820558AB5,0x41B47BEA5CE1A3C3,0xAA3D7A5491043412,0x38B7BF6DFFE66F74,0xABB6595F19D02A4C,0x9872F58A00BC78A4,0x29F1B1608E3F9EE6,0xA80A2BF317F81C6A,0x3961708B8A1BAE24,0x19FA2375D3CB354A,0xDBF28532B6501869,0xE28F11F5E30F1B75,0x4245BCE616A1E0A7,0x525BFAD0A6F111C5,0x3100541C97F23411,0x3CE6C091D3F62566,0xC9C50299717D6063,0xCD1DF4340FCA7A9F,0x5D9FCF62FA3CFCC6,0xBD0878DDB5DF0B81,0x6F9EF5F7D4F6EAD0,0x07BBE3EEFE428ED5,0xCAF3798F700756D5,0xCA12F1391D7D6F24,0x4938EBBA0FA0CC50,0x1CD8F4977D25D045,0x91455BFAE5B44B49,0x8E3C46937C0A29D4,0xC91365D57122B3D7,0x9A30612CA58DD075,0xDA53DC6963DE5990,0xD476B81830503552,0x8FF252E2BCFE8A54,0x673C97B366A97E5E,0xE76C8BE519BD4597,0x70EE887C73B835CF,0x54AFF63AF9760A21,0x7E2736B4838A79A5,0xA6B7C829A35B514F,0xC7945D634CD126DF,0x4AE165E56DEF261D,0x081EA8130C35B456,0xFAE85C2699B56B58,0xF972279AC3F4F88F,0x10983D98BB99A195,0x399E19B4E929CA99,0xC2D281631F49F45C,0x188DEF82B484E145,0xECB070334B55D635,0x21537041446A8151,0xF56361016BC4208F,0xB19DC27E6F6FB63A,0xF8DC7DEC49446E18,0xC1F21D3926DA99F2,0x031A361796FA4839,0x763D91F1D45B3540,0x804EFD781173E5B3,0x48A014D63733A091,0x817F01C50E8B4B74,0x9648A7396963A5D0,0x3844FF4C5A163D33,0x47DBC28801BF1614,0x98FC411E81AF303C,0xA7845168136035F7,0xBB96B281B0E4D0BC,0x3020B1DE888BE078,0x9E0F1FDAA8A71F18,0x05D25B76F6A4F679,0x8EC7B41AA5B3E575,0x9BD169C2EC7A420C,0x23C9B4BFEA5CDA11,0x6FAD1C6F019EF07F,0x0223244FAA281663,0x42BC221AB778AF8E,0x4B5741F4DDB8FEDA,0x05B347CE4208EDF7,0x5F4BEB0EC7E99C0C,0x193425E201A220E5,0xD5CFFC96F2D4CC94,0x94A15D5179DE8EC7,0x1C24FEB6FA384B12,0xF391F6C064F1A8A6,0xFEEC5B7447E6385F,0xE8B9599C61ECF9DB,0x564EC82BD9A59E5C,0x895F6FA4DFEF6B0D,0xAE5F57185C480F53,0x97B862FC74605B08,0x0B04178EE1BF7166,0xF9AF84650D425CC4,0x6774F047108EF2D3,0x6598B8525BE3E468,0xD29E3AA096D450A3,0xD7DEE2D44A9B8511,0x8F6147B01F28C8E3,0x6BC269A1F7BCD4C0,0xDE753AABC3177848,0xC91862898B42BEC7,0xB0587875C6485B65,0x886D5B356EB4D0CB,0x91300D1D2D7B94A9,0x19220D91E6FF03B8,0xDAA56683CB3CEDFA,0x90D86E35477242B2,0xA8FEA1927E185A21,0x6C52A0A51BA2E519,0x0B9728F8A1AEABE8,0xDE7D02ABEF4DE954,0x6D9E43E775598B0C,0x00DC836FA92DB9CA,0x7B2694EFCA25FB6F,0x58156E88D3183E32,0x7BCCBE5F1A13F8A9,0x51BCA3EA398BFA3E,0x84BE0C310218D9BD,0x43A9ECA3D8711A4D,0x98C87B22F478C6AB,0xB3CCCF083DED0B7B,0x9A5A8F9E0887ADB3,0xC93BF2318E174EE1,0xE669B00D492BEEA4,0x7163307F356F9458,0x853963606A1FF9F1,0xA575DCDB3FE5B944,0x742C0A070334400A,0xA5182685055BCF7B,0x18C24CCC4C69466F,0xB43F72E68FDA9272,0x67A34E09A9CD9D07,0xD261121CE3A014C8,0x31E302C0C9E6C6BA,0x50B9A0C5A20E5B50,0x35FD169B7CAA9264,0x78E9D8BA0C29CDEC,0x12ADFE007304FFA9,0x1CD8CB0930B5D314,0x83AAD1862B40074E,0x07D6C8B5F1FF614F,0x1345AEC19948C5A1,0xE12E68A948164A9C,0x3E75180C88FC1219,0xBF41A0D27D41DFEE,0x9F5C717907AF99B6,0x54CA97DDDE22F4DE,0x3BC1A6D5004281FA,0x97BDA0D6CD74D17C,0x76613AA8439D3930,0x741CECF78EDFC300,0x2E0446AFB53E5A4F,0x7BDA9A49AE1D6B2B,0x9958CFBB7E75F15E,0x523E7EBDAA1750B9,0x7223B677087602EA,0x75F8862B5B61578E,0xE74A75C13A52B349,0x5CAFBDF33BE58BFA,0xC2DF9C815CAC6F40,0x5036C8C4B20BF858,0x20417B34B256B0E0,0x609C3443BD1227EF,0xF6167C9FDB66670B,0x67B7DA11B8893EBD,0x264C40BE634073C0,0x709323AD9373A8ED,0x0C77F0EADCEB52EA,0xC81A2F5A36D1842B,0x5D8894910C3C460E,0xD84DF104F700C38B,0xE603EBEAC07C508C,0x8FEEB9D2A6ECBBF9,0x8AFAEAB58ED72AD9,0x6BFBC4C0C7B5C403,0x7A344B9F3D57E35E,0x7014F4D406F212D4,0x9C43177DD2D22132,0xFB6DAD6D90517683,0x8C1E37761730DD61,0xD9FB934006126276,0xC118BCC70E73AC57,0x8A014A38DDA3BB05,0xFABD1C746B340B32,0x93EED7AECE69F3A2,0xF1EF85AAC7646580,0xE99962D70FE9CF90,0x004439DA9661E86F,0xCD071E337F63BD17,0xBCC3CEE0CF9DD29D,0xC3134BF3EA1964A9,0x6099B5B1D46C89EA,0xC8449428D5B4AD8D,0x4CDD046C2AAEA566,0xF5F716BC9F9B2731,0x418367782AB6D021,0x02900063A150F3E6,0xC3787169E29649CC,0xBAF147B004873283,0x1DC257F087B0307D,0x2D6FF60B400B59DE,0xCB23616957A7D080,0x0278050F7CD62212,0x3C5B970DC419FEA0,0xA4B17D10468B9931,0x24FAB77795639FDE,0xEF1B7751FE01B484,0x59DE23E640F3408F,0x985DB02C53A0DEE8,0x0148FD4A8B3AA255,0x6035AE30BA0B21FD,0xC3BAE8A6E9A52712,0x56B07693F09E1734,0xCD0E5A1CBE034B54,0x807D0C17191227D0,0xD7BE5AC398CC9FDA,0xC51D9BA4F329B39F,0x9F6D15AAC9A57DFE,0x7792386B2791ACFC,0x3475828E2C38FB8E,0x07E51CFF6074C462,0x47144D4D21ABD196,0xB4085E7A9F4F91AA,0x1F377F0E28C365F9,0x8EBFAF73EE428B57,0xCB46792B4A6E509F,0xAB38CB1C9A095792,0xDE7AB2142F18CEC3,0xDB7651ACFDF3E80C,0x53B1135B2031CFE0,0xDC75351EABDA8791,0x6009313208D22154,0xC168E4EB0EBBEC7A,0xC597797D9A1C936C,0xF3AEF4E0D3011060,0x7FE78F95AC62B7D0,0x2CA5793E48C8CB23,0x05BE414720FEAE11,0x253B0364117E46AA,0x0AE7C323558AD856,0xBD2BA3C7ACDC42A0,0x14B015F246A82936,0xFE5379E786880F44,0x225D36E6ACA42168,0x49704D9BCFF3E04A,0x0B022A19AE5BEA13,0xE6F50DD521C12BB2,0xA6630CD40FD0C5ED,0x26BF8EE1996B9E0C,0xDF5D3AB87D53DFC2,0x5442B67AEB892AD6,0x6482F66631E0C72B,0xA8697CCD7BD1AF3F,0xA36EEBDA03FA98EF,0x6B6443DC8AE4BD16,0x0E1DA4F83CF13274,0x3CCA37CB71D9F92D,0x1BA22DACD33E8918,0x811B72469A2A9B24,0x08D4772594D93B15,0x500900117A5D0985,0x81CDF92108B1E027,0x13988032DE29EF64,0xC295A4CA57DB4FB7,0xB5BDC4F7530E6017,0xE4CC2C21B412ED9B,0x82FB79F027419E63,0x2193B38D1777210F,0x3E3ED1BEBEF43AB6,0x01AE0EA77DE5743F,0x4977125E358DBB95,0xF20E9FA8C81E26BD,0xB8EE4BFB58CA9262,0x10E724D997D543A3,0x86A7CA812499912D,0x3F5EB23DBDE7A1C4,0x7C20A7C76D2487DF,0xCCD817B6429E0196,0xAABFF4934D83F8EE,0x40C9D2D8BB7BF0E8,0x545FF4269B643704,0xC429CBF92935905F,0xF8FF1664A3371C32,0xD5F4DBCB57A787B5,0x7E62692332E58CC9,0x637F720C6D5CB838,0x6BB91F409A9E8B09,0x47891FD0DBA22FAB,0x511D43A10063E9B7,0x29141269F7D8F36C,0x51544FED205A096B,0x8B1C41D9F457C386,0xB06E087349F19B50,0x7511422871C63E90,0xAFF570661EF1CDA8,0xCB4EE361E02545F0,0x520886AC716038AA,0x82D982D2C8CF2642,0x23435B7432FB8C6E,0x6A27D2CD2753E0D9,0x605355FCB251DF87,0xB80B19758457B795,0xAE528C21CD111355,0xB2F6C29B6A624426,0x2448B6BEA3DD6631,0xFE77E0F12845A147,0x67BEFA305FF24A8A,0x58751BC2013C6CE2,0xF09E760DD2890892,0x1F851E153D35D080,0xD7A5209EA7F7B209,0x251FF1F07249EB8C,0x5ACE3DD991BD10C4,0xD37262EEEA4F6AF9,0xB0C644D347C1D8FF,0x5BA3DF4A4ECEA97E,0x142B5B5A8B627A84,0x8AD0D60F3B9AC1E5,0x1514E5860E79E3EA,0x7DEC93A4EE8E85EF,0x37C44AA13BCBD29D,0x93CF171C779D9982,0x2C0EE26DFE8FB9D6,0xF49A1C38BEC961D3,0x6FAEC80A9312DD01,0x5BB2325AB88B30A7,0x4E61FE6B2B457A17,0x517586766832E4C7,0xCCFB9F07140D5AC6,0xE99AB8698CBAD19E,0xFA068C0E5091DBD0,0x7B0DF9FEAB70ECCA,0x29C0A58280D2A70C,0x2AFD3D7DAF79F7D9,0x0E4742DCB1501B6D,0x2280047BCA126AF3,0xFC442C3DCBE4FCB6,0xB97FC989C3A07E3D,0xD31B1758C1D9E0B9,0xE945F15454486BA2,0x5C5D68CE353C7FEE,0x1AFE50E5601D5C48,0x0C505ED3D33962A8,0x390D7A5CD4317878,0x07DF881566F0AC0A,0x4EF6BA28E86EEC5B,0x3459F3701E27C441,0xB82D2FB87838B8B7,0x06CB172C365B3C41,0xD431598F1DB5E47F,0x0A2EFD073C2079EC,0x424AFBD37DE06BE9,0xBA2AAF0CD7BBC56C,0x8393CBA82525FD80,0xBF136F34F832A27F,0xA8116DD4C48BD1D2,0xFABE55888BC5FEEB,0x1FF33753C8301DB2,0xD6B12099DE366DF9,0x8CC7C20EADBDEC61,0xD44C9A375765747B,0x90D05EFB5FE7FB77,0xFDBD97F4B0762237,0x738A3C327B1480FC,0x193A934225FB4E3C,0x0450CEB011036551,0xF71C2C90411BF87E,0xCB71EF645B0196E6,0x8868C498EF72597D,0xFC6E053181A2DBDC,0xC3B9A5BECADD6C50,0x1FBDA7BBE26CE859,0xC67EF24F3685AF02,0x92DA7F05AEED3890,0xD05332C5C6C2224C,0x17EE099B089A57CC,0x76CD1EDB02BA41F4,0x421496B1480602BB,0xF7E72A7EADA631F9,0x1463D71F5F238BEC,0xE74133E4416F95DC,0xBE1EBACDA180D8FD,0x9BB6DE56FBB62D45,0x5D1584DD8E6780CF,0x1C27CB9DEFC14EC7,0x186737E0A5F052ED,0x0F587FA5B4524623,0x4451810C2053884A,0xC26046FB399C95FC,0x798B7C3B9DB9503D,0x0281D18E2CCFB56E,0xA30ED0315FC93C0F,0x236352484EAD3741,0xD9EE21D45709BCDD,0xDDD9F480D95EEFC9,0x952A548BC20075BC,0x1A857AAC28CCA8BF,0xED9C88C0ACEC8B9D,0xB11F55C3F435BC96,0x44CB3EE8F8B9EA4F,0x3B9F1DABA723DAB4,0xCB9544F880F501AA,0x5FBBC9C118467BEA,0x3D5B610D1F90E280,0xD9EF8026DE4C868F,0x8BFC3477F2B96521,0x4C680B1FABB23411,0x3BA5761FAFE7F442,0x8F18DDAD1BA85EB6,0x11D78883FD3DBFB4,0xF4E24FE53F082342,0x211009368C48600A,0xD80AC3C6C8DAD7D5,0xB481AC2AFF7E44EF,0x01D7FCED65EFCAB2,0x4630E973749320C2,0xCFDB4F0827F4169B,0xCA4C983191C783D9,0xDE86FB6F8A81F573,0x9AB2706A88B40D55,0x971B83267DF67A0E,0xF0F1244D01F26F72,0x2EA68347EA1B33CD,0x7343CC2B0794F856,0x304BA7DBCF50E847,0x4CDD0F651E45DA8B,0xA5796956CD6BCC83,0x09C22F7B4623392E,0xCBC2C9B0ED3A9107,0xEABF336ACBD0BAE1,0x0E834B9849F4E934,0x4AE267089BE96A27,0xBF96605024885724,0x0D32C512F83B4883,0xF6AE3DF3ACDA7214,0xD367304737F105CB,0x53DFDF3872A4DB24,0x320BEE9E564ED918,0xB63E2FF3661D6938,0x40FEB5A502B73A59,0x4151D901E2ED2BC5,0x9F4D3FDBD58A0382,0x4EEA0BF672CA7EE6,0xC12A6BC390ED9845,0x13173D21292F357F,0x7D151120F5CFEA46,0x27C8B1F90C77FAF7,0xB0A6BB7F56C258C6,0xF6810E6BFB00B32D,0xF17E5AFE46E6B0A5,0x30E6155E7219CD1B,0xA0146791796D0110,0x06567DD9D09004BE,0xBAEDE168CF57EAC3,0xF65616C74EACED46,0x563777F180DAAC53,0x0E8F964C1D14738E,0x14553714A07BEFF1,0x86192B96D06393F9,0xC66B26EEC536A004,0x6DEC5879108B0590,0x61773B7381CA7062,0xB9D30D81D9A7CF3C,0x460A7D744E8D3473,0x9B0C6E41EAB1E68C,0xF102F87403CD5C2A,0xA9C37EC4323AA830,0x275A2092A5364EBF,0x29B7B995DEB45CA2,0xB94A22E5965AA0B6,0x5761C13532100A97,0x8DB7395F568FD63F,0xEBADDF85FE085B8D,0x8B504768F2BD96A9,0xD9FDF69CE60E4FE1,0xA1B80776E9C63565,0xA2E1E11F24FE6B40,0xAE93D7A59C98F472,0xF1F0A45D778D4DF6,0x06F24F962C585964,0x9052C5A7B52A4543,0x786420D0B7705D42,0x0E2F5E0B959257D3,0xE7FD00F24620BDD6,0xE8D33D5CE04F8FCC,0xC006DFA959488A46,0x263281710BBC6C69,0x7175BA682A09B003,0x4DD273B2A40C0187,0x1C99820BB11F528E,0x068D5E16BBCD4E70,0x93D5EC0219013B66,0xFED04792F15D7175,0x439F04A06023DE86,0x25338FF50E45345D,0x16743BAD8EB620B2,0x36AAE74DCA433BF4,0x4B2D646B75A2BE65,0x3394BF62C9EC20F5,0x230CAA731E611AD4,0x7EC76C8D4766F005,0x51F66B84AE9891FD,0x5662F9F8CE1274CE,0x5246DD37EA6FEA35,0xF324E203F110A2E8,0x9ADA4338B220357B,0x0C9F5F9E7135458B,0x0B5E8F4BA744FB04,0xAD8B88BA1EF197A9,0x06D2324DE951FE97,0xF6147AA43983CEBF,0x00B9FFD72FA5FD77,0x5788E43DDCFFD5E4,0x8B4A10F119C5081E,0x012470BB03C6BB70,0x4B565EBCE0D62424,0x23885334C73E1F81,0x0327C0CB961E388F,0x39A0D59A026C411E,0x611B8317A87443B0,0x545E913A3B9F9B66,0xE40E6A55EAE2F6C6,0x33354A1E2762D8B0,0xC3011695947981D6,0x6D449E65AF4BAFCE,0x99D64BCC7FAB92C8,0x3973F64F4E812BCC,0x2285E8E55DE0DED1,0x9671E1C8AD11DC45,0xCED71A32178F6C28,0xC3D28A238DF7B2F0,0xDF1ABDF9EE97A514,0xEB3CAF3492A4ACBB,0x661F1D0CD4B22BC4,0xDC1BD9A370C2CAB5,0x913228FFE9779068,0x604EED7C71E11D2E,0xF0E7DDDDF3747791,0x3DD6DF2A2EC98CC6,0x6961A9BF3FD2861C,0xBFC13FB3846B116F,0x17F64FFBA9BA6537,0xF33B8E66D45979B3,0xE8C6E35FAE401BA5,0x6E552EAECFC5DFFA,0xE3B19DAD4F180489,0x8CCAE40B872847F1,0xC405061FE781980A,0x0FEF0464FE1DAA61,0x5C98AB26F6943B93,0xF9D3039F5E99312C,0xCB1EEF6F1CDD3673,0xD34ADFAD4D3D19D2,0xEA43D69D85618099,0xADD57BD5B97805D3,0x6A7F5485EFA2ECA4,0x1CA5638F0617CBB0,0x2E588956B1417E63,0xBB3EA79B0C3C7C44,0x31CF53362D569C38,0x3B1D312933833FB7,0x86187CB980C9F0CA,0x1BC13F11355CC633,0x9DE9C66867224220,0xAA689FF83A4AEA9E,0x76A90772B290076C,0x65D9A05D2B81EA8E,0xC595DA894F41B36F,0xF7EF25EC21E2AF48,0xC8D7F36FEE0D056E,0x987446BB22428459,0xCEC3B977D92DE4FB,0x28313F1F55D0BD36,0xB9414C4A55509D99,0x42E57AC292C57AC4,0x5A4AADC20D70F119,0xB4A32114963B7FC3,0x5DCEF1C17A21774A,0x15A03BF3DAAB61BB,0x21B75B3B72AFE728,0x4900AA2C70C932D2,0x904D9FFE8A10E22E,0xF6A8833FA9606D05,0x4D42B4F0FE76C327,0x3AD12B4F686473B8,0x3C4B68EBD8CA1F98,0x7A7FFDE4DECAB667,0xD24F5196757FAC5B,0x5F403EB90CF2CBB6,0x33E5BF8AB8FEB0F2,0x3E00D81846449935,0xF5C3FAA70A3A47E2,0xE90C52D964476D66,0x319AD0115971296D,0xE266E0B00041C6FD,0xFF755DE5AB654E1F,0xB6EDFDD86CE415B2,0xA7FD557B5E3EF2E4,0x780E8E6376E810B3,0xFE6C09E75A9B086D,0x3CA78759C71139A7,0x592FFF5CEC6C22CC,0xD95D65B950EE5965,0x3DA8949B9B91CC74,0x0018F13D4707857A,0x4ED4F26F5DD03401,0xF7706BEBDCA4C54C,0xA0086613CC0C3335,0xC3B588634225B14F,0x729B0CEADA7658C7,0x49B35B00A7FAA45F,0xDC9FF52D2EDB637F,0x3A9EDD879412C5B5,0xF841973EB23E2F1C,0xFC6E9455A8BC0C17,0x0F3A9569BEDC2E71,0x856111888AD94A63,0xA230EBCFAB871C18,0x0D2DC6B53050E7E7,0x4FCE28F4DF9C39D4,0xCA9D6D8DB0D5B44C,0x2B6BDA7D344E9121,0xAF412FEB3B28D758,0x97A519D3B2A3AAE7,0xC170F47D529C8D51,0xEDB45910EC88D3A8,0xA8B155953F0E30A4,0x4F4301E3534C4B7B,0x235D928745CB8F61,0xBB451351A5FB0985,0x3C65EF41D29A74B7,0xFA99377666D508F2,0x6BD7FBF382D6402C,0xD8B979357A14E546,0xD92E33B813C2231C,0xEC43DBC483F5152F,0x728B97A876176D86,0xC36DCBDD5B6CB743,0x804A2E2D4855B445,0x82710C4B75ABCDC7,0xABC3F5248940DF47,0x93CC16883FB38555,0x8AF6AA85932D6111,0x2D38542A570C04F5,0x06F06D3A0D06A764,0x7C8E999242F75506,0x5EAFDE58E8E6E610,0xE043C2B50525EA32,0x191BACFA22EF84B7,0x45B3B3C7268B2752,0x1563EBF2F1D2D72A,0x4CAA1D07499661E8,0x5CFB4135A9C8D569,0x03EE55A21064E345,0x9A684E2C1403ADD7,0x168747A83225ED7F,0xCF1089982F40B77E,0x9834B48E3BAB3434,0x2A21F126A54420FD,0x6131CE40C73CF20C,0xBC37E6C35C8B9760,0xBA84DBA22D9972EB,0x0CD7F98DFE67E6B2,0xAF830932AE396937,0x72FCFB1D921B9764,0xE0B03131BE9CE2BA,0x9343C777AF6168CE,0xB466993349909CDA,0xAE2954E8C4B1FF52,0x6330FCB0E73DAC42,0x9ACD342D05CE2924,0xCA2C2A11655D3418,0x7C96F0A54D1FAF6B,0xE7CCD0916018E64E,0xE6E08F5D65C4BC17,0x77C954CBD1A39FFA,0xAEBE042DECD1CE95,0xCD1172EC6C4419D9,0xB4A9EFB0C847CCE1,0x29B176C93B723738,0x479DC343DC8B4A53,0xD873F17B074B5ED6,0x8B985E59233D36BE,0x639A48842EB80596,0x54D77D9EBA7692D8,0x83B5CA69CFD11F67,0xDDCBAF7F283B2A43,0x56F90F07A91F3E33,0xCF458FD3B712D5C2,0xDF785D30E6A091F0,0x2E7262B27383BD03,0xCFE8F02E56DCA23A,0x383FBD37C46CD4EE,0xBA81F5FFA535C580,0xCF21FDFD964DC63E,0xC91DD1C4F20D99AA,0x9CD7AC2D4B20F8F0,0xE110E1A5943FE402,0x87B31C5CF27D9D71,0xC2CC9E6606DDC94C,0x1052E021D6432853,0x8DDBDE2B0EC5BE0E,0x2BD29323E5FFC519,0xBE232A323471DB56,0x9E38E5C0BD6B0077,0xE8286865247293D5,0xD37ADA6987028E6E,0x8EB51573FE3D9DA4,0xD7A2DF895A04F640,0x2979EA022C7EE85E,0x7357B926E97EBAF2,0xE4B562358F96EF54,0x6299F3AA2D39F5BD,0x9E56D39187D8D644,0x0FCE9B92D24D9458,0x5DE27A1D3D9319A0,0x356E2499DB2DF050,0x202FCC8484EF5583,0x6B6052BE15114580,0x9B3F20DEF26B7E64,0x086D1D5754491EAF,0xDB16874F81639A21,0x54A759C165592C4E,0x702360EB91B580BD,0x765547498409E6C3,0x57375571F53E0A6F,0x1F0993093E68BFCE,0x40FFFD27A7C1EB4E,0x6AB5B3A3AE0AD101,0x4331141A2E6CA94C,0x35E8409C71985EAB,0x3A2101474C62F571,0x87332867BA226A22,0x34ECEE196B321550,0x628C77427CC3C9E9,0xC7DE80C165907A85,0x939BBC960368170D,0xC2B1739B7AFD1872,0x31C42ED283BA8006,0x9237F58B461586D1,0x8FC23E5BD80C56D8,0x65739CFDDF4A3EC3,0x1769F073B22B721C,0xD44AB819551A0BD9,0xCE68D1649FA764FE,0xD34D393573A2BC1F,0xC5127915CB27B853,0xF106D88D903CD01E,0xD69D4EC3EF49B954,0xEA83B1793C33B576,0x614F9F8E0A5E8495,0xE4B2A1BD706020D0,0x394F2D3E95BBDF58,0x2BF13140B9B36FB1,0x1E7796FA906D368F,0xEBF965463984D829,0x24DA1AEC66E3B12B,0xDBBE2528524BB15F,0x8D507B457A37DF4B,0x902FC0AEEB3502AE,0x40AA7B496E5A8E3A,0x51051F84A2579BD7,0xE33A44476743EA0B,0xC3662A675DF6CDB5,0x0FE0058408EA0096,0xFA682DC50C035C2C,0x157BA54C7F57C95D,0xB5496DE9E2F48ACE,0x464FE9B32AB96E6B,0x1C0B0B094220CE14,0x92FD09B9AC096DCF,0x0D210EEC5D2B13ED,0xA5EFB2C99BA40B0F,0xDF4B5547090AD6EF,0x64694093DB1A248C,0xD438CF6CE7118324,0xA72D25654CAA2EE7,0x10A673AE862F6755,0xAB34AFE10620D5CE,0x958324EE3A1BAD56,0xE3F14C1F883202D7,0xA5B03631D287C75F,0x8599613BC54E0538,0x4F1DD5955314FCB2,0x483ACE4A02D0B3E9,0xAAC6B956698E7DAF,0xE22025BF88AA1DFD,0x626255EFB408CE48,0x529F2F51C402BD68,0x3A7170F3BEFC656B,0x4C752D2F3DE6A9DB,0x47CB411A73748676,0x0BA480202B072F7E,0x7D1307BE091E63BA,0xA365AE5835FA6AC9,0x27C267D19800B0F6,0x6324C64EA3AD7B41,0xEDACC9878ECCAFF0,0xE1AF5095CE17B7BB,0xBAFB30486167AD3A,0xB7765680B3376BE2,0xEE3F327C85F9BD2E,0x438A6AEB3463B4E7,0x8A3284EE358935FB,0x9BA80D854B5B3B63,0xAE97306815FE561E,0x6A1CBE003720646B,0xB9A19C0A191B656E,0x880AC0A4057843F3,0xE05BD3A850A9159D,0xB213F13B4C72948F,0xFBE3B5770BBBE887,0x364A90264F1ADF18,0xAE30DAC4A64D055D,0x926A61FB738FDA1F,0x75740BF4D08FEA94,0x8CE95364FAE6B21B,0x778F3D88FDD34CF9,0x1D9ACF091A675ADA,0xD0E10798B2670E15,0x7A1DDE71FD9C85FC,0x4C061EC990DC83D5,0x7A38437E69539283,0xB50A4F6D1318BC0C,0xBEBCDFCAC736A97B,0xACC66A6BE45F5D42,0xD3631B4B36738356,0x2C8F8464391CFABC,0xD9478421ED0DED60,0xDB1FEE1C61AA3EB2,0x985B4AE4CB8EC10E,0xDE2803BBCD36F13B,0x9134A369608BAF17,0x8A2820063238821F,0xFA3FBBAB3F390E04,0x00D0F4B551369CAB,0xE21A5FB03D277CDA,0xF65635D01CE9A12B,0xB8AC5EC3D9F48834,0xC7DB855142F89AAF,0x36FE32090E14CCC2,0x91FF0EFCAD1E1B75,0xCAFD9F2F020602F0,0xF274D38CF94101F9,0x3276C7539D5A7EA6,0x8B048748C011779E,0x999E4CED32B07D82,0xEEF04B6310E9C1A3,0xA3949F2E8721BE6C,0x05CE96D5FDFAB65D,0xE749960DF60A8D63,0x5E402F9B50277030,0xF5DF2F042B0E2B5A,0xB0BE9A6344ABD3A2,0xE167ED97F4809F67,0x3E7C1C2CD25D23E8,0xB08D7CB32E0EB2FF,0x352DAEF01B39CE76,0x9CAF172D2B4D20D4,0xC3E89F70E2343F65,0xD3BB28FE1A03E7F9,0x316DE177DF951F3C,0xB7B6EC2128B3E76F,0x4582468CF7967A87,0x35FE9F276A63B802,0x9CF7A81A5B918BEB,0xC132D31DE6B21654,0x530CE292A6A2D5E8,0x97B7FB65C2A6EE2B,0x742F1B73509F8D07,0x74CF4B8F0B6F01F7,0x92D03E3A6054ABAD,0x629BC9D93FB93944,0xD266F0B641111B7E,0xFABA18FAE31DE893,0x307EF21FFC0E5BBD,0x9DD4B1145826B00C,0xF8C5898CB9E671EE,0x7E2E36D05D6C6CA3,0xDEA215E19535E5DE,0xC95556D574B7A87B,0xF11F66836B7CA5E3,0x91F6D40AB0B69BE7,0xC7EC762A8232005E,0x06398735B66A336C,0xB9358375127B50B4,0x34A9794634123B36,0x21C2DAD3EE2A5B73,0x618B21608E1D4548,0xCF5390E878B550AC,0x43709610F13B0912,0x7B175279A65C51AF,0xDCE632A8F38BD6A2,0xEBCDF7BB1FC039BC,0x0A2F58380BD110A1,0x5800E5EE13CF54FA,0x4207F6B53618CE02,0xAB4E9502448C758D,0x046534C4D28318C3,0xD18A28D34220BE82,0xD8AB5D0DFB53ED37,0x20CE33B4DE6E2747,0x4826D706B46E4C00,0xC5EFDEF7CC7CD38F,0xF011584D8FD649D7,0x40C75EAC81BB56F7,0x475883F4BB232516,0x2583A096C34A5522,0xFF87C60E20FE3B2F,0x6B8A465550CFEDA8,0x5FB7DC52EA0108C3,0x7117CA35EA13C760,0x7CFF1FD7BD5742E6,0xF8F2A7A7E3464639,0x5854BA448156D88D,0xF3BC85B5BB62D21D,0xE1774A1B50C4AAE0,0x4FED478A098C0A58,0xEBEB0EB3E183F8B5,0x9D82E046AF7A0EF5,0xB9A26C8E70062379,0xE1F5CEFD168CCB48,0x161309D607A071E3,0x3A917545DAD40D84,0x70C3203DCFE0C77A,0xE71636DF6F1578CB,0x20E9BBDC3AD39A47,0xE191FB0F79498632,0xD660172EBB4A9882,0x641070A20BA07AD2,0xD9EBF3C06D72FAF5,0xE8693488D68800A9,0x08E400359BDC2D4F,0x54C29191E261E7CD,0x5ADC35A22D74F250,0xD8C445B0AA081BC6,0xA53663DBFEDA51F6,0x954A59835D08C094,0xAC613FAA9B11FBF2,0x3A965722A945A803,0x9661B3BB46DA0CC2,0xA910915EA7B7C9C5,0xC418F555EADDD216,0xEF44AD9247C8B5BB,0x13C17C451B52D890,0x8EB06A18AC0C56BA,0xFF19E7B1E0650C87,0xF86A9EA9D6AEA6BA,0xA2676021B2EA60E8,0x5F0BDC2FF61BC040,0x8021D7EA925D4BEB,0xACCBDC4D231A0909,0x04737029CD80A224,0x5644658D798FECA9,0xB60EBAE8FE62E6DB,0xE3381B90D795DFA6,0x8CCA438EB4AE9396,0xF97267D347DFB774,0x479D134F6AAB6AE3,0x9FF21ED4CA6D196B,0x347486F4BCF476C0,0x90AAF9F43DF403D8,0xCD35084F19E23B30,0xFB10CF3AFE18848A,0xCF0730BF1EB8D340,0xC0D321D4A764C140,0x3DAC7FC4AA6BEDC2,0x1E71F3773AAA396A,0xC2864BBFB1282B7A,0xC71C76A12908D180,0xD1A6417B6FDC1434,0x0E4D4AA351838C35,0xC60505311600123A,0xA7F0A06ECF268586,0x801D62541D0029DD,0x0403FD001EC64914,0xF2537533319724D0,0xCF9C997DE31A5D52,0x8E66F50A6DF0A1E4,0x284875B4036B2261,0x54AF5630C8CE3FC5,0x2EE008273770F52C,0x83949EF636BDDCB2,0xE5CBDF68854E7BC7,0x50652B8163238828,0x9120974F939D8D67,0xFFDD3BD3B0D058A3,0x8FEBBFFFA5398E3F,0x075EDBC702CA2AE2,0x237B5F2CADAEE043,0x7C5F6E833C59F5F2,0x7A05AA79EB0625E5,0x08FC75AD16BF8D2E,0x3C25B71667565062,0x657C1C55BC02BDD1,0x88C1EDF87C0E7806,0x0112F2FCE9493C79,0xA9243195BEA32395,0x67EE56CFE3B33760,0x6F4B0A9F2DCB0E4E,0xB507B361F8C1F01E,0xEEE24CC99370AF0E,0x30447EF86CF3441D,0xB1FFB5E6EFE187CF,0xE0EB86AE056EDD7F,0x67AE07FD6C3E987C,0xAE838C0D50DAE2DD,0x5BBDEE7DDB6BC874,0x07909AD1AF206CC0,0x471F0C4AE26C7E47,0xB46C65C1DB392C53,0xF31A3657FC79B5EF,0xE204669F781B57A9,0xB05F6B6943892F62,0x6CBDF56A6D28A9A9,0x8E7F3854982A5105,0x65CE34289376C5C0,0x92ECFD1CCD13E609,0x99EA7C3FFA9E0564,0x7EBE4E5D73F3CA5D,0xFF374499BFD4D71E,0xDF47FB205CA15ADC,0xC1BE3941EF42A213,0x26EB5B85EB0A9F87,0xE239AAC425D6986F,0x688738446AC15500,0x1F26D1B3EA401CD8,0xDCCD45EA40405770,0x9C62ADED76B145D5,0x67DC9F49C7C81BB6,0x5339BA1A7B1FA1E1,0x143B57C3F53A026F,0x83688EC55F09CF75,0xF4D624959AE04AEA,0xB196387CB6EEDC2A,0x1E08F959F72A9A77,0x4FB389A4AEA7A8A5,0x39AF4913B4EB5AC8,0x91A17EF56DA490F9,0x6168B7C707050A56,0x628F81A86449C46F,0x9347EB7BA9E78779,0xD6F8853FC399878A,0xB4DBAB3072629DF0,0x003B926963A6377C,0xA1C8C996BD1C9FCA,0xBB358EC336D53C6E,0xA11CEA9E8CE73B2A,0x711DC0674B9D0B72,0xF39B3AAF7932B804,0x768E716A24157F51,0x44534ABD2C81D557,0x9D3354477801E1A4,0x9FF0B0B9875D961B,0x8B55426A5B806401,0x1428B8CFFA7ED81F,0x1198480E7AC45757,0x38210129ECDFA55F,0x64AA734B8FE18D74,0xDC11DFF4F4471E1F,0x239D3D13F23FF36E,0x4CFA961460DDBB9D,0xB22C68B1A6B96D19,0x122AC7D440C3DE5F,0x5AD304EE9A35639A,0x3C1FDBCF015BC7BD,0x3FD24D5EF751B9B6,0xE09826DCA52AD4E7,0x2C36B07E079AB290,0xF452EE6A2C839374,0x269A91488014DB15,0xF89BD676BE0EA547,0x10E52812E2346C71,0xBF7453142E4FB03A,0x7E9E5D6189FC8284,0x3A9B40DD1333E59F,0x7CF2B807DEAE69A3,0x3AAE0BC42A1EA021,0xEBA9C567B84AA91E,0x0995709384A5DACB,0x833BA70A1B30EB27,0xA25DC8853E67056F,0xE751506F0C7DB441,0x12F7F1AA8BBA25A3,0x65FF0560ACFE4E6D,0x2F637085210B1C84,0x226D6DA8E58CE8BA,0xC6AFD9CEA4740DAB,0x2F1F384F817035DF,0x7BB2C66DF17D1853,0x1B8EA90FF8DC212D,0x7285C4F1B06861D0,0xA1ECC8031B2CF018,0x9C02F2E53E4BFF6E,0x1983DC39D9F79184,0x06B70DD44E99D515,0x9851CCCD79F27903,0xEF98D1D27826EE3A,0x228CABD258004B2C,0xE1130F80AF889427,0x427FD8CB5C3A6E51,0x96C0DCD64E9E6F1F,0x91ED4BF0386DC011,0x1202A03E0C1B4D7A,0xA0BABA2D1A13B575,0xDDE8E421559A2B82,0x8C917BEE6E2A1317,0x7D8C0B47E44F52C6,0x46822663F2DEE60B,0x99B31552F73C6347,0x9F7407B9D584B5D1,0x58A3F99F085F0092,0x51947E152DB22BB0,0x0BD6EE993C7E9B2C,0x394049CA0379C489,0x36CE0E6301ACDF31,0x0841F8CACFC6AEB7,0x864A5E26DB93D3FD,0x297BCAA6844EE337,0x18A20E90BDE0876E,0x50BB32D6C55AF2BC,0xCEB3ED55685E1AAE,0x6F3EDD757C9477FA,0x47BAD516610B0D74,0x9FAE4481556C5F6C,0x285EE33228DB49CB,0xE56C1555310F1421,0x7AF8575546265413,0xA8951A2B95ABB29F,0x82DA3FE52B8A13C2,0xF05EFD5A00031111,0x277FAE3B45DC73A2,0x2F2632A8E6B64B85,0xF7ED2DBEDF613FB4,0xEDC91EED0DBC67B9,0xCC80E6BD5C327B29,0xFED560CA14858913,0x39809C569DE0893E,0x2D1D53DB966E6426,0x3F3086319BF1B254,0xD2ECB1ABF4512451,0xB19B3E76890AD6B7,0x9A376A096448C1C2,0x739974DC4DAAAFEA,0xB5ED544D7567FCB9,0xED0C02C6EEA4B15B,0xCAEEFB436E473564,0x20C0808C3A086F7A,0x74CA348C15345BB2,0x73DE5596421DD986,0x15F98270509F97E8,0xAAF2F3483413A9BC,0x63D3F8839E376FAE,0x151A6D86801AD864,0x94D5B78C9E0EF35F,0x7C8098DC8F053AED,0x20D45CB2A9A5B569,0x5103F011BD8D4788,0xAE3D1AEA75371C46,0xE0B1496F5CD6BAF1,0x79F48ACAD1EBFDD9,0x5C59CC8B340BB392,0x9D6030DA75BD3876,0xF5282FD858ED2EB3,0x05D867EB62CCCAA9,0x83952DC3A95650CF,0x8105C58C93B58E5A,0x29A3984B5E404294,0x5E8BB5C75BFAD735,0x3F2AD3BC74DDEF2E,0x36BE324717CC417B,0x7317779BB40A556D,0xA3B6F7728351A86A,0x451F52A0CD9F6C74,0xB032F7FEC6CA9664,0x35EA1805BDE20E77,0xDAAD998A74649B75,0x309E42F9BD953522,0xF94A9615551EA8CE,0xA2110487DA411B07,0x6A8820DAA2E86518,0x5495882E4B58F1DC,0xD861B9043D5B4ABF,0x3FB88863DCD9D850,0x860F871232EDED11,0x2E6A4CFEE922CB16,0xB269AEF400C2DA17,0x454E8855A05DA627,0x4C18F7CD4F8E1347,0x1BCE954890E3F902,0x708FCC43F1F63829,0xD9986A165B8DBEAE,0xC15385B96D3B2A04,0x5E334275C6A46747,0x16942C7EBF8E0CB2,0x86C72703A50502F4,0x951020434E1F9184,0x8E968505148C8548,0x71EE2298595F981E,0x9528C6755BEE002D,0x5005DE6806BD6D52,0x4022E7E132C407FB,0xC783DF42A9310E28,0x73BE051C27773BC4,0x764BBED05A9D91FF,0xDBD5CCE494E6DDB5,0xF6084DB5EF377DE3,0xA32E4971DC69C608,0xC431F76C9E27FA7F,0xF6CE497656420E16,0xFB190A46C20A1E48,0xA291D43E9DB74226,0x4F4B53622DC6C874,0x8ED096E31F471497,0x9C7945D845E7F503,0x1269502927B3821E,0xB60CBCFBD0B7C5F4,0x00CAA20C004DAF19,0x15C5F9CC21DE3F99,0x599A31A384874233,0xC14D66B8471F7065,0x798EBB62EB7A8CE5,0xC1245FA1F8C7F0B8,0x187D599564B80ADA,0xF2670DFE317CCE80,0xE0D19952627C5538,0xEBD362B788EB4CD1,0x545E868E52CE71BD,0x3AA9C3E9F51CC30F,0x06E0C378B791262E,0xB94E316D91B522DE,0x4760A1E42C86E575,0x6692221F2586425F,0x6B2954F4AD12D453,0x80B9A0E4A362114F,0x48AE156A02AD947E,0x1A9911FA4F5EDB5C,0xF51DBE8FD5A8C8F7,0xB214C9E495D21527,0x946C2F3E2743B88D,0xDE60427118CCF38F,0x5531DB0AB274FBE6,0xA23A58387C9A34BD,0x328D5B0C038FF7E8,0x98BE51E0BBD64D25,0x8C9D74CA235D896B,0xB8FFDCC0EB0BF094,0xFA6AD6CCE484CD1A,0xAE6EF6FB6FB832EE,0x64C36A4EA9EC2DDE,0x4A03E9FA0CAB16C1,0xB8F73FD8C7D53976,0x11B59AA44B3F88B3,0xEAEB21A83329BCED,0x16E3F38D68D1E8A2,0x46DA2A6D522F3C0D,0xCBF4DD9612EE2B02,0x7D7BA330433B98C0,0xE2856C1077DBF7C7,0xA80BBAF2FB68A4B4,0xE7943085D72EA7A5,0x62D13829DC5BFD5E,0x6F292013EE7FCFD8,0x1216FE3D3FF7CEC3,0xE18AF5335258A54D,0x0BADE7C2452282FE,0x5CC00A4B23406AFF,0x4E61894C2750835C,0x0CC915D2EEC37619,0x09009CBC0DD94CB1,0x8EDC6DFC67707DBF,0xDB1839475CD21122,0x584A70F45DC88904,0xF95D41A0964835E5,0xDD109D99A71690BA,0x504AF8131A8A492E,0x32FD0BF2256853E6,0xF1C43E4DF9D0F301,0x9A6751662111F02C,0x045A8F406EE1C364,0x0528282A7C41ABF5,0x480A83A99C62035B,0xD4935D4E251F5BC9,0xE60191A6DCF9A371,0xE3EE574DD22828EF,0xA712BBB127FB23D1,0xA4E1BF9BCFC4DE42,0x787AFBB16F1E84DA,0xFF707E6F0EBE21D3,0xAA7BC0E879E7E0AD,0x6BC74B8D68CD24BF,0x88D6A86F5509C937,0x64622E86006D3207,0xFEF9EC2E326B219F,0x520AE146B985F7DD,0x5998E874F939A1E6,0xF128984EB6B3AEA5,0x0F470973F10F2AB3,0x6D926438BEFC2CBB,0xFA82EFE63DE3A07B,0x897E6AC9859B976A,0x4754573E9D9EA78A,0x22ACDC8B0848BC8B,0x22DEBD9D9B5176F9,0xDA3985D35352CBDA,0x51BE47B19E8CA687,0x06AE7151272B1073,0xAC2576C789037810,0x00DFE2FF241341DC,0x634925A3D7ACA2F0,0xEF98D815F131B8CA,0x0A193E7F141BB691,0xF81C98398EDFDE46,0x54B2AED457D4F203,0x8AABAFF1601BF592,0xD8A53CF4D0EE9AB1,0xF42BBB060464584E,0x1694A718617B953C,0xCF14DCC20C26C92B,0x4417987270907CE6,0x3ADCA5C5F6FA1283,0x4C8256621A4AC39D,0x3C23F154450BC792,0x69708D2B8074A8A3,0xC505298B5A545BB6,0xF2AA9613A4B08BEA,0xC6E9D85F83410F5E,0xAF68BEFB66AD746F,0xD971D8DF63651B9A,0x722E17C25DF89FA9,0x1E18AAE62B027067,0x59E2670E1A3BB768,0x0E18672A2CA6A433,0xDCC42557747BD021,0x57FB4AA3C39DEC72,0x2D7B4B2F90C07FBF,0x9617EBB1F36CFA4E,0x66AACEC0204E4F4B,0xA9BE5E659B56A165,0xEE68880EAA730A64,0x790B3DED5012BB71,0xCF3AEA8BA68703B6,0x8ADA78C64414FA58,0x0BFC5B0524ACE9A5,0x3F6925898AD59B9E,0x91770F92F31D5833,0xB5BD5C0AEE72D8A0,0x182C1ED1C7AEE2B4,0x26860A9123EE4BBB,0xB99FC209E1689E34,0x281F463D433E9A67,0xFF6F81B746DC41F3,0x47C635EDBA5FCB91,0x5D55448B2867A2D4,0x78EF4AD51DB7B8F2,0xBB8B4EF69B96BF23,0xD48154260A5A6909,0xEBEE53AF3DB0F605,0xA0EAC33EF8670A14,0x916FA3C36FDB43F2,0x7F75A9B218206E47,0x8C13814393CCCD86,0x0BCB795F0AA86A82,0x1EB05A0837B838DC,0x6D7D61F50C3B8DE5,0xA55BE27FE84C442C,0x7519A81296D3212D,0x21DD9189F74BBFF2,0x85DA052A7B57C4BB,0xC1CC7B766FB9058E,0x2FDA0AD216D2C53A,0xC2E749FB5E63875B,0x9315FBD3C3AA839C,0x7A1DE757CC3EFE33,0xA67090CFC73E3737,0x2B680275C53A1C6F,0x7A5B45AD1F41B903,0xE5B9AFE12F215808,0xC00CB33895C1E5BC,0x5D58EA95D7606531,0x2500C79B535C306F,0xE7896273781156A3,0x4D2F987C71FECF3F,0xAB4ADF7B1C2BF9F2,0xEFF82FBA46B20235,0xF961471BFE78731B,0xC27C399015D683E2,0xBC5F3ACDF7F690A8,0x82D846E88BC17B2C,0xDC242DD5E0E38B69,0xECAA6DE529D2E0FA,0xA3C6CCD431025AE3,0x72B0E6F5CB8FB678,0x25CA7181CEE6F756,0x5C07E7AA0D537DAA,0xBB363119F5B6E347,0x26CDC4A20EBF0AF8,0x750E06326061D041,0x38F970C0C0FA2E9A,0x67FFE9337298C16C,0x3EBDE2008DFB8524,0x80876A130B4FC62B,0x82A6294AB21AB1B9,0xE6D2763918479B42,0xEB489FAAB213C921,0x0FCD0FB1A2A058AB,0xF482640FCDDD9191,0xD720A8BB4DD04802,0x2464B148DCE57388,0x93E8EDF7198C11A3,0xED03677084CAB57F,0xC069C600BB802BFC,0xCA5A16847AAED3D9,0xCE4612C9EB81987D,0xB18D06A878A76BF8,0x83D7776A99781F5B,0xD4CEE14193BA7C57,0x679A2CE02C8A6FCB,0x5DDAA28BEF3A8C5B,0x7E47E77A0DD04EB1,0xCF46A27732984592,0xCEB093CEFBA2AD34,0x46D5C0E728B0A75D,0x810B1F50F487DFCA,0x54CDBDBBF7E04833,0x1AB1DEEA25B54436,0x5191774DFADFA7C7,0x5EBF986EBBC23BC0,0x4CADF06BFFC1C76D,0x682CB8E65AAE1D13,0x09E5FBBD4FEF5A26,0x6B049D4AA2E43C81,0xB6008F35124F58F3,0xE195B7E4945D0165,0x06324B194E859BB4,0x9B9C0ED458DCA0B2,0x8BAC9983AF6AACE8,0x9AC320809843FDE6,0xB8123132CA197D05,0x87C7003B7CC816E3,0x7A04D8395CA88F41,0x3879B80E0BF95C2A,0x8695748CAB3FA1A4,0x5EBC8394C9C6627E,0x9B81B9B81B97EFD1,0xB545B2AB4B0DF00B,0x9995A4F62FB86D84,0x0D385BF93E73303A,0x51408972A035ECF7,0xF86663B0F473B7DE,0x88F2DD2E602A021E,0xBCFCC30C0E437474,0xC39A959BC8D4FC68,0x1B3CCEC6A7DA813F,0x42B5C872DE57FDEB,0x718B3B4CB1277461,0x693DA4A946A5B4F9,0xE73D18E71409176D,0xFA851892324DF082,0x538D141D7600E886,0x6C6F37F41267BEFF,0xEE459677762FFF38,0x086B2FCB20A4BCE4,0xDA508321A9EEEE9B,0xEA6C33E01B9A6671,0x624572A739781014,0x7D5860D3249D4502,0x0603E1122B59A88C,0x26F6023264E38FB1,0xB8A059D3D9C756B3,0x76E05B26838A5EAD,0xCF7439A4FAA6F834,0x8541F74388FDD27C,0xA903356EC7A218DD,0x023E83D4587DBB5A,0x21A723191AA22CEA,0x1C94C11602195465,0x2EFDE0BFF334E8C2,0x8F3440734B2A71E7,0x508DB87BE239F1EC,0x44C954BF61A69EE6,0x27E422ADE996F6F8,0x28EA675CE03F18C4,0x0889A84EC92FE80C,0xCE37EA189CE9B557,0x4FAEE97D9DECC5BA,0x1DB4C4818C10390A,0x9528EDCA619B44B4,0x82DAFDC87F4AB83C,0xB32E44EDF533FD03,0x7322A0FD84DE469C,0x83CFA6259B76C72B,0x9AC4511608A0A49B,0x07F77B3D3DD6C388,0xE3AFA480EED6AFF9,0xAA65976EAAAE8E7D,0x776154B9406DBC12,0x4C8B6E8D9238DD06,0x623014FAED3DB092,0x4A84857DAFFF5C7F,0xC3C62D2D789D080D,0x2EE86EF60D5465A6,0x2751AE1EC1A1E358,0xBED6CF36D65CE2E4,0x45D5A97E0348403B,0x3C4D7605231488D9,0x9E828985C56A722E,0xBA6AEE2B161F8C14,0x7C7A9CECF330211D,0xFEE1606AE47F7ED1,0x18701453A5D7EDFC,0xF2B3D8D137BFDCF3,0x4AB2ECC546B3CFF5,0x1E0D4CBDFD88DEC9,0xEFAF60CE864B8D7A,0x152D3A74D495C45E,0x79608EDEE3F8A27A,0x11DD65F3650DF00B,0xCE382CAF2BD4331B,0x923E95302A4E7F18,0x94DE82E9E6A1B55E,0x986E4EE770E6AE64,0x937BDB2FE2254642,0x6AF359EB06F830B7,0x2E43010680F69F6E,0xAE81630B632E4ABE,0xF18BB7A2F09242B2,0x68AC325A1ED91FCD,0xC5692DD5E731E91B,0x4A5AAF99252B6DA1,0xF72E16664E68D734,0x8B55B12AA78F8C42,0x4A38B4A90A13968F,0xEDCC1CCB8B4D890F,0x71CB0ECF7782A8AD,0x3B5E6F1F6D911F9C,0xBA5F4C5E286333CE,0xC02AE91CA17AC18C,0xF69B2A6F371DC068,0x5AC85812D5368355,0x0CD32A9D8F0D02E8,0x9082F946C998900A,0xBA6CC1E2A5AE3467,0xAB223D1DE8475E30,0x208D4063458EB810,0xC4B31D260117B4EC,0x7E918F0D782E38F4,0xB957DEA3B5E87501,0x45418F9135CEF5CF,0x63937EDEC6A002E1,0x9EFBCDCF79CEF99D,0x50920F30733EB65F,0xC21EE251B7E34160,0x18062E2DA299126B,0x312D770AF6DCFBD9,0xEBFF3D4C414444D7,0x62B3728DA0A3C3D6,0xAF468CA1EECC0D0E,0x4C145E3FB3470F62,0x2785F8F5D419111A,0xD2D1B5A0432D413E,0x9B52AFB81928520E,0xD89F86E5F8F5B5D9,0x9912ABCC28A1A2B2,0x39FBC1411210C19B,0xF0D0A2FC080F4C15,0xAC79EB8CDCF8194F,0x181AA15B9258E4DB,0xA2C5735F33444BE3,0xF71B7A7A5DEE7548,0x32F215A72509E534,0x94EB7B2B009BBC57,0x41A489E86C9969B1,0xBE4868C1DC3C3D67,0xD8FE538DB6E527F0,0xF0EC8D66C0933910,0x80B387537BC9A614,0x883D34DA6DCCFF64,0x5188D2E90E55BDA6,0xE4A41E4D76F69BF5,0x617EF2685A79BD7A,0xC84D51A14EDE2C22,0x0147B3FCA92DC58D,0x53AFD4E3279A904A,0xA9F69B79E01B15B5,0xBF3C563AE2C3CD60,0x0F4ADF8DD5365C7C,0xEAC09E8E5188C3CE,0xC2681DCF9E23C977,0xA672DA7818087A77,0x1E11286D7DC56894,0x9CA790FA024DAFC6,0xD65B5EA8F1CF69CF,0x6632403B74CDC5C9,0xAA992326B2D06B9D,0x825C6519B1441A83,0x920D9727288D31D5,0xA4796D43D50F5767,0x5806E9A0F904979C,0xFD3DE7DD9FAA3494,0x30C19A78B5B66516,0x28F3C4A5D1D95004,0xCBEF72993D0A110A,0x0D9A8E6B31D8803E,0xE1D3D51345FF853B,0x4BCA5D94DAB6B47C,0x044FFCA5EB943DE6,0xBA2F400169357031,0x32310A576FDEAF9E,0xFDA68F3B8B2F0D3B,0x6CF63DD1DECBB4BB,0xFAE7D77E2E12BB48,0x55DD5E0B76414D2C,0x430689AE6C949761,0xEF6F28D07B769B47,0xC76D946D63A1BA8E,0xA666ED775B0DD266,0xFF1EF468EB25C951,0x897029A7A076F152,0x5E8C5677A001DABC,0x4A67312863A3C5E6,0x66A5A4D099747A8A,0xD4284A8186205C76,0x40D5BC856A3FAC52,0xD43C3786D8371480,0x8AF181E2E75D5FBB,0xCEAADE70B18DF7DD,0x6D03310D7707D357,0x3AF0A3765785669F,0xB4EFFE1D99D86006,0xD9765D1F5A2CE691,0x11FEF6B67CBEE196,0x61170DD56F026C8F,0x837E4CA4BF567708,0x0B895BD1163067B1,0x244371F535C4E410,0xF1A3E570A307A4A2,0x216A67E6BFA48866,0xED30FF4BBD7CD940,0x4D00795242CD8FBB,0xFB8F9110C34AC9E3,0x2D1FF12C1C5FEFBC,0x0D6C6563B3E7B231,0x20D7D39BC2BB139B,0x8894D5D9A88A5F27,0x62AB2AE7A539F38D,0xBC77B30D02E6FC24,0x069DE6AA9947DEA5,0x7059FE0A3D48B2D2,0xD3B05D49F563D430,0x9860F58458F67068,0x62BD695089FB694F,0x40E71DCDAB5A5044,0xEC77BE0B7FDD33E3,0x471C0C1A441DEC80,0xC31090380EF8D7CC,0x954FC5677DA136C5,0xC3FA85CF42DC36D5,0x03526B30A432969D,0x1755335098DF502A,0x20D329B75465E58F,0x440636AF062F9373,0x2A04C72B43376755,0x72189E4439E94CAF,0xEEAE1AE7E96B2FBF,0xF1FE955B863AA3C9,0x46256CD91C4F1541,0x00EA141178BCD19C,0x3F7A73C0430E6923,0x1A91D2C5B2A37450,0x2210234E799A6E8E,0x0853F353ABF81DCB,0x88752F880A33E492,0x7A58705F16BD5754,0xBF048D687B6F8F1C,0x4B8958EB0793ADB4,0xF1AA180E5DF0B56F,0x63D2F76AB2C26F54,0x3A662622821F35A0,0x08A6D7ADA3FBF220,0xEF8C82163E9EB93E,0x921B678CB49E46CB,0x53450EB914E6E785,0xAD23C701E2DE8276,0x569616E8B502C6F6,0xBE1EE77DA83FCF16,0x38C7EA0D360E5BDE,0x7ADFD5ABF5E62DD0,0x5724ADD3818C17E3,0x30A94FD18C69A47C,0xBC7311416A45B2B9,0x998BD8288B42126C,0xC4106055672A6847,0xA8F397CAF37D6F69,0xE1D133F31D68AA33,0xB0911D1D4302CA3C,0x2054213CD71B9334,0x311BCB9C89B705DA,0x4D1AF479E93EDDFA,0xEB89DE2A964EFBF5,0x397D8E3FED305D2A,0x147F154464620E8B,0x434A315EF9F2F66D,0xFC48EBEC9A10EF18,0x342AE926FA28011A,0x1FCF44552BEBE8FF,0x9B7B1321FF22177B,0x7BDECA0AFFEEA65E,0x6A46F815F971E361,0xFD5E3C40EE116665,0x92B2EC998D6DD479,0xACDA965562C3DDE9,0x55DB7849613D5204,0x6290B2E25B939160,0xD54F8354B095ADDF,0x7679E61E5D7B0538,0x43645BE2236AEEC9,0xE500FE4E55003FD5,0x7F63F18796806738,0xDD48F4F277628190,0xB1C7C0E30B3DD012,0xD108125C1009924B,0x494E98F0DC0D3CBB,0x67D1892EE236E81A,0x6E8176A07524A432,0xAC5E8E3EB5AD7526,0xDE92468F3AF4B3C4,0xCFD23CDFD4FDC92D,0x34014CDF40D9ACA9,0xFD04E0687CD7F86F,0x7FF2B72B44E500BA,0x95FB353502A18365,0x5726816DD09B3C5D,0x2CE07587BF0C44E9,0xB502C75AF2F9098A,0x67BA1DAAE20B093F,0xD3CC0129343EA6DB,0xBDDEE2186AFEBEF7,0x4D261DD504FDF4DF,0x0A028098EA652573,0x342BFBDF161F15A4,0x0828E2550A6A9318,0xDC97D11446090FC0,0xFF9678A2CA4CEA38,0xC3F3DD3A7779EDB4,0x1A8BF545AAFAB36E,0xAA2FC2C02D553E2C,0x424ABC169F5FE124,0xC9E78A0B0AAFCC02,0x80B2A02AFAF8E5FF,0xAB103A38F8349391,0xEC8016348C911E8F,0x0E12714CE6D1F9E5,0x59AA9709A989D99E,0x8BD81B9601C91935,0xBF49600DFDC7EADF,0x9D94B243CE85829E,0x1B1BF8D008E9CE5C,0x3A9C6B3EADDFF183,0x8C86484AB422EDA7,0x3E10E363F1886176,0x7CF87D95A6164001,0xC9199A1670663D22,0xC42DFE74C0E63668,0x035F59B66941DA04,0x76BB75302DDF8869,0x0CD0A9D231FFAC1B,0x5D772EA8058DBB25,0xCF3F76DE72BC9049,0xFA062328DF56ABBC,0xF9AECBAC64BF71B4,0xACD0211148A0AFA5,0x67192FB2138A87C3,0x42D00A1797E9A5CA,0x3F7E9BDA3AB08D25,0x27EF265BFCB2AD0F,0x7C3D116A35B9E8FA,0x4867928B2E42A47F,0x4E9E44174F3DFA20,0x2B6D2758FCC57897,0x13A2D8BCF6879E75,0xE2837CEDD9F2A8AD,0x284D951D1031DBDE,0xDEABE1B356388D8B,0x261A9E8921CEDDEF,0x5747F1A350ED1713,0xEF65E33951DFED40,0xD68E1AC14A502C35,0xCC88ECDFD5E6441D,0x69FDA2C2C31FE1DA,0xD66B1E72E1835266,0x660C565C00C74AB1,0xC63C81C019E9AA78,0xFD468222E6C8FF42,0x2B97A24F7592D80B,0xDE8B134A3C8F0667,0x1529616933E95BB2,0x997F81E08D6D5AB4,0x7BF0613806995C47,0x08A4A742D4E2DD72,0x83C5A2413F65C5DE,0x6193329D576F74DC,0x0D83895FC6FF7E29,0xFC94615C7F27E398,0x06B45B9A0CC392F4,0x72F47A735849D608,0x7441B3E742679435,0xABA8009E61949C50,0x36B83F19D12CD965,0xA944A5AB7DCC273A,0xE990A5CD1DDA832F,0x0249524024C0C815,0x85D1715E0F0708D2,0x1D11E3E189C0C955,0xA1FED0135CD20CF1,0x16667CFF2617FDBB,0x69AC8648C1F630F7,0x4AA39A5E65370912,0x4188392B08E51E9C,0xEEB375D6EC2B78FE,0x625639562B633219,0xF6602B885A7DC43C,0x3368281F7F6A556F,0xDB1818213AA48A4E,0x456D5CC2D1960182,0x9DAB5BD017B85CEA,0x15862E0449CE45E7,0x649619864E31FC2A,0x51C9B570E937AB76,0xBDDE389FCCA6432F,0x28FCB729CDDBF035,0x9FB50FEC4BA01E35,0x44C1D4F1DBC088B9,0x5646DF78C1347449,0xF85DAF147EE5BFBC,0x15C1156FDAC94F31,0x8CD2E10B57BB9CF1,0xA0DD12DE2EE7700B,0xAF04EBCE8BA65642,0xCEA376712CB43D40,0x12CB6F778BAE3F36,0x8B69832AC6D14DB0,0xFD98F01D25D3A10A,0x93B1513F9C1A8C67,0x99CDC3389C38D1B0,0x94AFCA77E8D6C73F,0x65A28286C6BE5673,0x6C1B973824D9F96A,0xCFCF30A2972C1749,0xF8D96804DA470EEB,0x655D89B6EAB8F5CB,0x418CB73EB82400AA,0x833AD003ADC5AE5E,0xEE94C1A4672792D0,0x37F9B0CFCA5219E8,0xB6B27EF7FD14FF7E,0x0A917137C9D3AB85,0x6D53737E4ABF05B2,0x5097391150B5B79F,0xCCBE3C684E98E948,0xCB504FD6000269F1,0x8E440D310D56D808,0xB74995C2805E98F7,0xB7F3248C878CA72B,0x4BCBABA3F569F9B4,0x0877D2C35254147A,0xC041332BF904F5A0,0x0A88B1EFBFC212BD,0x7FADB239F6A2677B,0x12AA57459B84D16A,0xE2C9AA6231AA95A0,0x8EBFAAE8FF75B576,0xE5485D6F79768B3E,0xAEF882DCDFF1A8AF,0x4486169A1CEF8734,0x51982DD6CC41440E,0xD2764FE8D15FF402,0xD6314E0718813B71,0x9BA2AB9E0318A9A2,0xEFCC70B196EDB378,0xE66EB5C06DA27189,0x1481DB1BCF4530C1,0x1E16668BB4C40C96,0x31827B9031885EB2,0xF0491026E43B6007,0x934293201164FE4F,0x36BADCCA49BE4E8F,0xFFA870211482D761,0x271C907FF97C340E,0xF62C5536AC366F1F,0xF3EE999C691EC1FF,0xCECE632B18660516,0x3C8C455F0B53EB11,0x87FBB3C5F7CAB8BE,0xE16F527BA60F3C27,0x21CE9CC0D4A5CAEF,0x15A6376B9227AC1E,0xD957B6838636826F,0x219C600878C28DDF,0xFF37D84C0F4814BB,0x3489C7CF403F58C4,0x5ABEDFAA74B89FFB,0xE1C994A9D01F19E2,0x74F88C26FBFA4728,0xC9D3AA99C80C56E9,0x91D1CB0DAC50C182,0xE4B20672D5D8786C,0x120A813A5AF67063,0xB8A2EFBF41B6D121,0xC91752F611D1076E,0x0269618921673523,0xBC1DCB91BE12331B,0xA29738B56036BC70,0x1F9740ED7416C65D,0x2CD032F5699908D0,0xF07341D07D58A2F9,0x06EC29281F662F8F,0x2BE75DF58A82C2BD,0xDA0DB896617B69A3,0x813FD57E909AC75B,0x6D26474FCB4CD44F,0x53548EAD95AC8103,0x6AA414DEA36B4DBD,0x6BA097FC3BE1FDFD,0x005F28253CFD8E13,0x36C73F331D5DBFB5,0xC7FA65E3390520DE,0xBB4933791ED5094A,0x9740CEC1A8B37974,0x876FFB0A20102AD7,0x6AFE6A96CCE7FC50,0x5253FE63DC256C4A,0x06ADB51998469E59,0x4D9A2A414C7575E6,0x9F84DD980C6CBBB2,0x292EC6F334EE0075,0xCF4D2CBD7445CE73,0x418254C21C9BD4F6,0x94D1BD31BDA9769E,0x1D08FE7E6AC6F10C,0x501422D698FF07D1,0xA8E39816D19637EE,0xE9C26F242ABF5193,0x5A2E1C5AFE0C3955,0xFAA3BF10C18BE6D8,0xBC351E396FB80174,0x12D5EE8228878975,0x6FBD60BA00678781,0x96334D5D10B652D5,0xB9BF3B959EDDD0CF,0x54FE2EA34D4DC1AE,0x6CCDB996CD633D0E,0xE6784F83EEB72DBC,0xD699F1D9C7990705,0x7DC1D6996F77717B,0x2058C2769FAB3F27,0x3559A489D0D94AB8,0x5D4768BD82C0627C,0xFCA120E556F8956E,0x9D0A60138E380A59,0xE46A51955C347B7F,0x3313CDB27BEE921F,0x000B0A28BBC8747B,0xDEE3B0394B1CFFEA,0xE24815DE437FD106,0x8CFC819A5D41A707,0x03AE44596D8CF103,0x3A4AA40FEB664BAC,0x38BB063C87621EC4,0xA063C8F9531F2248,0xB255B90D75A1BD3E,0x406F02C200417AC5,0x1BF642964F00D9CB,0xA1FFDE843BDC9ACF,0xD4B98770584752E8,0xD6777FACC398DBB0,0xF1F279A3B9DEC1A5,0x797F29A8E5476758,0xE2639F4C052B9D0D,0x406FDA4CB4825F60,0x46F8026181A55060,0x40CD32386981D417,0x0ECFD59D7C7364E1,0xD16424F34B477184,0x3DF89273ECDD85B3,0x840FAADF4CF08D8C,0xDE82DF67B59FE740,0x2B6A75F5D3325F7E,0x551E885780B95C71,0xB371507D04FD12AB,0x933DF64019B15609,0x82E74FC800E4E58D,0xE8D3BFF9BA139FD6,0x9F6E6EAE71BBAECB,0xE4D93D3BD22CC5FF,0x95DB99CDE056D977,0xA6BD2042CA7AFFA6,0xABCE3E59A70A11F1,0x2FC6B029A3134947,0x96C48FB241A643C3,0xB61185DF90761364,0xA894E5D19390960E,0xF8771F90C8C09A5C,0x07A62462C78BE27C,0x720A6D0A2C61F388,0xA66B247CA3B74179,0x335215B334E2746C,0x1D803C0895797F08,0x8E348A137A0F1FA3,0xBC5E58EAD2B4F656,0x38CBCE38F3281D2B,0xF18E6995866DBA72,0xD0A31F2AFF2B0FCF,0x830E6BD672944D69,0xAD9B5C8CB51606B0,0xCF2BCFE196BB4F4B,0xA7C1C21511CA8841,0xADB17A1543A732BF,0xFD267866B8C86F27,0xDC4209C7040DEF1A,0x60EA7DEC04291F15,0x709F56981727812E,0x9B26D389B3B43E41,0xBAA3C1096A3ADEFE,0x6D0AD9478D770BBE,0x1270C40FF35C42BA,0xDD507EF9BE06B3D6,0xB2AC362D278AFEFC,0xF52224775941269A,0x1E58A46AFF4227A0,0xA960B0D56C750A56,0x1393AF0C6CFB784E,0x17ACB3E40A55C995,0x8DA7EE84A65277D7,0xF80CE5973B23DEFD,0x09B4045BF24B08E0,0xA6E00F3E9EC1DE94,0x87339B3C1D7D3598,0x13813A274CC4C464,0x1C9C3A7602106350,0x46FCE71E396D5618,0x9CC2888E9FBA2DC5,0x84C01EC32A9F1EC0,0xD5D1F271D22DA6C6,0xC9EADE52BE75BA0D,0x6C9A68434EF00BAB,0x4A2D0DA7C11099B1,0x4A526A9644738F9D,0x86E0BC901CA5E653,0xF2207BCBEBFC5248,0x368DC3368896249D,0xFB5003F7B0EE7A2E,0x2EA078A6C0ABFB16,0x4105E6ED9A602865,0x0EBB178AC4A55AAA,0x711F7C732FBA3614,0xB7A5CEAD60FBDBC0,0x90EA424245E32131,0xA584269B030390BA,0x94F880336126CB6A,0x8CB2637F87C256A3,0x61FADB66E73B6A23,0x3F16790F56FC26A3,0x1F9EE5689F55B9C4,0x3EDB85FFBD012A74,0x194A082D568A984D,0x5C76B3F2AA2C953B,0x941D4622277BAE3F,0xE82339E479C4D381,0xE97945B3F0AD150F,0x8B1FC32ABD58FF71,0x259DD748055555E2,0x364FC8A836FAE8A2,0x6846D3B5D2AD0F79,0xEDB7854B94990060,0xA2C94272131A932F,0x19702CFD74EE5884,0xA7F8007053A0DF17,0x750A48580E24E1E7,0x8C1AE4AC6FC64C7F,0xFCB8D504BE0393C3,0x104638085C391772,0x68B2A595A2788C08,0xD152A559F7E2A214,0x4F655994343F7140,0x5688424A967E0F86,0xACF4182C4E4B5DB9,0x820263F7A5435EE1,0x3119EE71928DF4B4,0x7078469771687484,0x45DD86889DA14B7C,0x18B8F442CEEFCD28,0x9746BFBC070495C8,0x7824276B3D3CC8A9,0xE005E873045F0A85,0x8B0CA4353CB3C33E,0x3A48FD0BDCC8D4ED,0xEF635A5127538BAE,0x1611F0CDEBAC99E4,0x7C108F84EDDAA374,0x16EC2B2C7C2D1947,0x9582E68D870B9B5F,0x4A139D084743CBD3,0x633A9B9C0A93F762,0xCFEADCD15C1EC8BC,0x3C90D73356AB6273,0x7E7EFAE693BC4B7B,0xF8A618711AD95DC3,0x5BB36F5276BCF7C9,0x3B0FDA7CBA3502A5,0xEECA88F13D150526,0x3C6BDA3D10CBC8F8,0x8D0FA2A80038A8E3,0xA322D1A7D10906EA,0x119B65630A09BB50,0x61F84F1081D6E9CC,0x732E701DA49D401A,0x233092D992351143,0x91124CBE56B073EB,0x1691BDDC936B3B4A,0x40622408D4D44A52,0x1551228BA1A0974B,0xEFB6804A91A7AF57,0xFEF57F2B0D1D899A,0x58E1ADDB183DE5CF,0x697EA41363EFABF5,0x61D5E994A7BAF005,0xD790C205EF2E2FDF,0xD89059AF10C61056,0x7D7284D7DF4DAB49,0x0EFED94D2B998631,0xE089EA055E74275E,0x11E056059D8C6F90,0x220EDC0F93DC9F94,0x3316AB36EA758D24,0xA756C1FD0AA0B399,0x3B70961582D0EAA8,0x3C6ED0CF83576407,0x07A49B70FD392B51,0x3B94F8E6304C2D4D,0x682D0837B4E1FF5C,0xABACC94256DB031D,0xE5DC6ABB2994058F,0x12A0980977B29DEF,0x17DDAA5A855B6F96,0xF4D8CC98439F8361,0x3FF2E189D2E1D758,0xE5F8492F1D34FECA,0xF7BB6BB76C34F854,0x5873133E2153B418,0xBC0480E83CC32C6E,0x18E186E46864C65A,0xC8D1372DFB97FB54,0x4FD80103ADC0A7AC,0x01D30BE3C00A2E5C,0x2AF5164995BE83BC,0xA247CB4A2AA5577E,0x3D4B0E7208AE6EFF,0x260281E70FC5AE7B,0x727B959360DB9FA8,0xC94BC77853D06032,0x28BC2B953A84FDA7,0x5E31480403592CF5,0x8855B428E4540E37,0xF1604DC6A6CFD768,0x600AF4086CBEA5FF,0x02F25CFBDBCB7B44,0xB66321DF804BDDBF,0x72ABF3C75755CB22,0x7C8C615CAACBB51D,0xFCB60D4970D86F19,0x8DA9896F787EA769,0xDB561ADC95F28AD5,0x9BF3021CD82F6790,0xA4B1BC1CB02CD322,0xDF7006CCEEDF296F,0x182D048C3B8864DA,0x0D31D6F766CD0BE1,0x08C198ED380A5842,0xEB74E803C7BC20BA,0x9918F6ED0EF9D1CB,0x945AE702CC8415A9,0x6C2453828A97FE44,0x51B3B50168A3A2CC,0xED7B4569054FDF69,0x01E7FE42F1A0597E,0xADC267DA0B7677CB,0xD8D50DF8895711C8,0x962BD0B6348D105C,0x95B3DE7C14CE8C2C,0x95D3A29CDD756354,0x09F466BE6F4F228E,0x1BFA00077A84234D,0x56C49C9589398951,0xD97CA56F690D4A88,0x22075AF371BF610C,0xDD823016610DF2E2,0x2A452CAB18DF03F6,0xC6F3E4DBD997C58A,0x0E09C5E82611C022,0xECEDD5D339EB3C26,0xD10DCC9097BEA3CC,0x32FADF55688182C1,0x6E6AE47CAA79D598,0x67A165DC30D5FD52,0xC6209947766B5557,0x2D35FEDDD9B1F689,0x79CC2AA7139A0E7B,0xD7736DD56F9FE197,0xDA4ECEF10300729E,0xEE5C91AAA5FF522B,0x85ACB04AD835BAF2,0x9E0848FE62DE62E1,0x8182DE14115B3878,0x11FBF2CC32193044,0xAD364904D9682292,0x52812C8273ED8580,0xCB96A3F9C9E31C8E,0x15F5343165069779,0xFFA59D2F37505D51,0x3B581D711233340B,0x5E4F0FE67459492E,0x2DCEE48BF81383A6,0x7E055E2579265BCA,0xC48A40DB16ED5C9E,0xDD1A2EECF3030C20,0xB96350722F40477C,0xDA494A28AC0DEE18,0x48CDDD85D796F844,0xB657836A8FFB9EE5,0xA0B19EB42FAF59B2,0xCA3B928B6C370251,0xEAFCA54FAE0DDDBB,0x6D193CF243222B53,0xE239F3FD4F6B33D4,0x1B16A523C22773B7,0x4042CEF53FF831E9,0xB49229B9793220AE,0xBC9E9DDA60B7E5FE,0x5D9F19154DDE29A6,0x3C6F2D94E300BB5B,0x2148B921CCA217C8,0x0F1DAE562F989ED3,0x3FD6ECBE96200551,0xF58DE708247AC119,0x6D11661057FB1A25,0x4CCEC14847B1C949,0x6FA43C777E68ABC9,0x0F32A7C9BE29B3E2,0x59C6F8F75EA843D7,0xEDD6D06DE2BAAA72,0xE81DCB86E4E89B8D,0xBBB16BB85AA48F55,0x75DD6113EE9AFBED,0x4960F5A4F89D3DA7,0xEF592394BC0DC8B1,0x84F7ECFC19EAE078,0x63BA6FB634D8169C,0x011D05DAEE77C317,0x7E9C0643CD91A4BD,0x16FAFC52349FB6F0,0x6A28CEBDB2729757,0xBA5BC5860347482A,0x5C7A1AD22AFD725A,0x582CAB6D320137AE,0x1C9FAC465CE99F0A,0xB8718516480A8E25,0x49865722BC897D2A,0x795545978D7A1ACB,0x6671C7244EA8F0F5,0x54CFD1EED36AD039,0x2C2FDA995219C2EB,0x0FF332A13EFF7ED4,0xB6F040084629531F,0x4FE60A45BBC7A67B,0x83CA357C44FFB8AE,0x3A035E0759B57BB4,0x5329AD4695D40A9E,0x320BA40BD82AC2BB,0xF93410C975A1988E,0x96F5F573EAC029DD,0x12DD738A6EC9AD30,0xA2D7AA0D0C80CEEC,0xB9F239504427C65C,0x93D74D8C4F79B4ED,0x29CCD3AC542BDF2D,0x0F2FF60565A5A63E,0x202C350C2F195CD9,0xEC8A0E6E8495EBA4,0xAD4AC9B17F480172,0x7B195D20B7AF9121,0x924AC2A453EBA405,0x78387008E606124C,0xAD4751F9CA403297,0x94432A9977396921,0x5EF7FB635B56C2C2,0x10BF698F53A62C95,0xE795F2A1E636B046,0xC8564009FE3484F5,0xDEAFC6B8C864D4BC,0xBE326D2AC382577D,0x6D5A06431BD9D5DB,0xB3EF94C364013FD4,0x22D91A81021DB3E5,0x40E75EBCE3530C3B,0x4C05B58EB5AD5D37,0xD2E43D997C581522,0xB20689DDC594CE72,0x27DFE8A0194795F1,0xC5BEF8711A27F32D,0xB7C08501C9B352A2,0x6464724BB92537C6,0x4FC14771BBC7DBDD,0xB68C2318025EC322,0xFA7EDEAA6B2E55E5,0xC807F1C56F2997BA,0xF2AB8C4345D7D4F4,0xC1287224442EBB4C,0x25BC4D76FC93F334,0xF66AB01EF2C70654,0x78821F7B17793D48,0x7886AABA7DC6CAB0,0x8278A6C36369AED7,0x72AC6CC7199E2922,0x8CE652586DF3958F,0x1D05472C8D639081,0xEED500B216BFE307,0xA0BEE5481C26BA0D,0x3127E18A8928CB37,0x4BDAF02B0837CFD5,0x3C417F72441F55E6,0xBC04C5B8573B2A54,0xCF408F113A30480A,0x39C00F01372EA981,0xE15DDD80BC9734AE,0x2BF26824F791CDF7,0x7C4AAF8F3DBB11A8,0xC57B2F19126A8C45,0xC1FDE8F6EDD19C4C,0x362B13BEA18157D8,0x1D7B632843515D85,0x8A9F24A35318B40A,0xEDEEFAD416C4F70C,0x431BD8D95F7F84F7,0x808DE29AEBAC0A7F,0xE3AC726DA92CAF4F,0xEE8F4C74869FB369,0x799825C7BE937E00,0x8EAE92BB9D25869B,0xAD8A1E0770834AC3,0xD5B8639FA251BEDB,0x4E5C042C2B5306C1,0xE4ADCC31079DBC7B,0x4C790A05A21FD8AD,0xB91C795ABDD6E0BA,0x70B5841F108626FA,0x7574BFFE4E444F4A,0x59FAD04CC1FBC1FB,0x1CBD19A9FF74F240,0x3D839BDAD60DA56E,0xD31F64DB93636CFA,0x582F9B51460C6A0C,0x936F5D8E8D9B97AC,0x4A97BDD507B0D91C,0xD4F58CC2DF0A6922,0xEF597B4E21E85E23,0xAEF1A1680B3EF9DA,0x1C8CF7FE2378C7DA,0x7B75F94800427F9C,0xF5B1F71F9C8EC329,0x71E9712875CBC018,0x0D63803127A70DA9,0x10B39357B973F9B5,0x455A01488F86A019,0x5036AC032600B365,0xBC5A456DE8B117CC,0xBF333FEFAE898639,0x1BCCDF61641ADD10,0x024AAE396A242912,0xD5B952EE010ACB04,0x9BCA26AC497CEDC5,0xE3DF51562B4541E2,0xB6F4D6B9BB7D40E9,0x9570373512A29995,0x0DC3B0CE60E80D82,0xFF5B1B54FEC15D4F,0xCD01B61FF6815E56,0x34782C6BE89D3A68,0xA8DBCED5CBDF21A5,0xBD56D513EA83FBFA,0x710A20B666764698,0x26FF9BD37B289CF5,0x772F6AC2D33C0383,0x8A5997585B0B1585,0x78E5A905B2D246E5,0xBEE1CD95B8B5115B,0xDBAAD9094B8590AB,0x3B163DCD6D01F818,0x8536FBD7C177F7B2,0xACFFA109B13E810F,0xED0CEC6DDE884B00,0xF988BFA72A381A5A,0xCD5D5DC8AC4B491C,0x27F9267598721741,0xC9A88F77A3C47783,0xBAE7C8689CCB7738,0xF83D2367740F21E7,0x6A2E89A42CE7ED96,0xBB08E2360F8107CC,0xEE39319B6B4E7990,0xE4F045B6C50A7B9A,0x7D6E06F74D11FE20,0x4AAD3ECFA1A5BB92,0xB0A94DE7164FEF10,0xAD561F8A21012493,0x1ECF65F91FE1B2DF,0xC3DCA093A5CD3250,0x49A6825D3B0AFC9B,0xCB4F45F231E604C7,0xFFC2D33EEC45C762,0xE8A2FE013FAC5266,0xAFFEF7181FD41486,0x7311F1D9CA10DF63,0xA2A9F695562C6945,0x8F150FE6D3FABF64,0xF7BDD6EF583B2BCF,0xD7A9BED20B4D0CEE,0x42E8805F74B7A64C,0x2D2B3D9F78900B60,0x768B0BCEAA41B2DF,0x21ACBC88C09918C5,0x6680C7CBF21ED694,0x74564FD5FFD4CEE6,0xE126C43D8B123983,0x57824B8E7A514ED7,0x820B66BF7A128098,0xC617E6EBB91B84C7,0x642FC3EA36165B22,0xA24C160C59BF3C13,0x8D4D505A7D7A5046,0xC6A1A79A86F61D2C,0x21717EE2840D72D7,0x8BAE8828A42A7C38,0xBB1AE3DAE8715544,0x5324F2FDF82F28FD,0x59E0195EF7C68EF3,0x0BFF450E6DC08F93,0x73BABC33355268BD,0x97354E206A816958,0x141D8C612D1D7946,0xAB365E5BA7367F25,0x36AF3ECD48420B53,0x7C192E77A624C77E,0xEB564244AB80B91D,0xC03C20F68D0035D4,0xACECBDBD62AC77C0,0x64CC2677B90AA8B8,0x36029EB338683199,0x2FB96419D1D4A67C,0x0288D12DAC23985A,0x23D8E6ABA93EAF4B,0x9ACC0344E307AEA0,0x4A3AAB355103DA8B,0x7AAD01974CEE0D90,0x59127FFAFD7D6674,0x26E45F9911E52F7F,0xAEB957F154E7C691,0xCB3A1F04674CC8BB,0x6251A98312B8F484,0xE0B9D1479C151718,0x09B6A528C11606CF,0x1A4E3F07240E8058,0x637C8ED72CD9CFD8,0x4F0FECAE118283C4,0xC006063654277EA0,0x48DD17698D363E18,0x272CEA2531491161,0x21B812EB8C6C6CAB,0xACD66BB2B1C6A7D6,0x15DF186D28C06C59,0xF48EAB87E0A6CD31,0x9E38263D76771542,0xE5F368B3F55AFA11,0xFCFD24CB35258782,0x68CF492AD2EAC465,0x2E2E6E44EEEBED71,0x74293CA87100EEA8,0x029CC49AFC58C1BF,0xE5F00FB2EFDFE7CF,0xABEF7CBD984AA054,0x26D08D3D35479917,0x64BDFBE134104E17,0x9A70D27326F5393F,0x7ABD84188BAF7180,0x93B8EE276306D915,0x62B9FDBB6890B1D2,0x310A9B066B2007E0,0x0E91349BAC9E80AC,0x2383455E12B5FA9B,0x7FDD2BBADC8BB960,0x19A59D20A38DC206,0xE5FC714A6F79FBE0,0x19634CF2058595CF,0x5AE729615C00750D,0xB962DCBBCEBA3763,0x562DE025F06DF656,0xF3C6550EB2C55A9B,0xA62A4428DD1C80C2,0x7495F9CCCEAEBBCE,0x4E39C357E729D20A,0x649592AEB1B7F439,0xD4B86A85FE4D02B1,0x19939733989A9017,0x5CEEA446452AD5E8,0x2C96DC408B3562CB,0x47B4175A86489988,0x52B9B27F2061EF49,0x501197ABCF508725,0xB4BABCBD3A40F533,0xEBD1F6CBF1ACF8A0,0x01BE910F80B6C9E4,0x56A12638AFDBE84A,0x243FA42BA011FE33,0x5D1A1EFC81CCED5D,0x0C91D4B7055486B4,0x46A7DF5F48C37539,0x945CB72D0A14D2A8,0x9F2F43C104EFEFB1,0x729C813236AE1C36,0x083563B9C5EE2AD5,0x89227E6EB4B44F1E,0xDD703473D81A4934,0xA90C01ED6823D46A,0xC3D423C3E6351A57,0x6F5441695E846D95,0xBC8C51F5C72AF981,0xC081AC0105B08898,0x1A8D7AF2230D64A9,0x0F4A3F1CBF9A5D90,0xDAF54DB6BE1ABA53,0x27F8164128F3C59B,0x2A96D901B277DB7E,0xC0527A7A567F76DC,0x42E4B79469972437,0x3AEDA3EF4CE1E5D5,0xB763C3AB8499C221,0x923482D444596FF0,0x47ED08F2A22B57A9,0xC07C0310B2DA4B9E,0x59849D66F3DED91A,0x6A6BDE960DB7EC6D,0x946DF036D1854BD8,0xCEDE35DD50D56D4A,0xA4E0083B0713E457,0xBA0DA1A52F2A39DE,0xEE819EB3341A857B,0x0211743C26690B62,0x98BE17D04B184D04,0x8ED42D475DDEAA67,0x28774DFE3DDF803A,0xE0C041F75476BC6F,0xCD7F14A59214AC96,0x831DD865B8DA6F38,0x605B7F241B3A03E5,0x1F305EB4E53AE653,0xC229925B37F61027,0xABC8ED95691946FE,0x902554933CADDA77,0x53878EC3C18B5AA6,0x421D4E6928FF2252,0x75EF3F8319F13889,0x2850BB95FD19F03D,0x8F509440C07C40A3,0x1F5F230F9332B65D,0xAC9FB148BE833436,0x6F95F94448D56361,0xBCAC425EBB185001,0x1B850E6FE7994DE0,0x0FDDAC16777B2BD5,0x6DBB9A3365E2AD72,0x124D13C38FB6F3B1,0x5286545591DA64FB,0xA7963DC3559D630D,0x91CDA9005516C27C,0x16B78D2EACBE89A9,0x6D9381643546BBB0,0x9F198C39C5AC2098,0xCE9B9B16227AEB9B,0x72E35296DC800987,0x28F2DEC4FCF9C777,0xB23259D2698E25EB,0xE0EAD698D02FDBEF,0x679E7906B517E59E,0x76E7EC49D6D10FEC,0x3E56816E8FF85F8B,0xE9A818280E7E16F8,0x4DD24687B7513D05,0x544CA3317BA947A9,0xFA85EDEFD56F4412,0x45009C7923B1273E,0x0292699AA715D2E5,0xA4EA28BCC60E9708,0x44DD34189983788D,0x96F0A534A13512D4,0x172737A5D842983C,0x3E9D91BCB794BF80,0xF1F595E2480CE9A6,0xD8B113AE65CBD8B3,0xE704ED908E6E837C,0x7B6B35BF0F7E8968,0xEDD4EB2B5AAC5CC6,0x88BA1564BC912A19,0xD3748B7FE7F2FCA6,0x9D31B77CAF0AF9D6,0x1D71E16B72BFCC0E,0x5B164B74387106FB,0x95D870F56DB770DC,0x3FEBF99625F39ED8,0x607705061005D8DF,0x5C27AFA8C1DE21AA,0x4039DC3990CAAA7C,0xB4BB925EB675481B,0x9541EF28DD638A89,0x6ACD52D337DB0035,0x8910E0D5FEB30820,0x8F2C84436FD4EAC6,0xA9A3C1962B93DF2E,0x55253AB320C552E9,0x562E5736B95C71FF,0x41D2664AFB93149A,0x29AD8F48F99B60CA,0x86EC8C0CCFE3DCEE,0x2F3A73294CD75A34,0x48C824A136B7288E,0x4C5FCFF43875C544,0x297967EE46078BE2,0xC45357C4B3084362,0x589B9E3986EB2AEB,0xE91F481E6ECDB410,0xB008045B05CFECEE,0xAA79B12DB6658980,0x56A0EA09D8EB4912,0x0B917D654DC1C529,0x419695F688049C44,0x7848DE9D6B668368,0x03119C49E7FC52B1,0xE832F122A2C60198,0x3B310C0B76B61A45,0x17C3BD9D7375CD1E,0x168EE617D289F9B9,0xF39EB97E3A058701,0x61B79004A87FA379,0x9423E9E33467334C,0x932E763B83C0CAFE,0xFD1CBBE3DAF06634,0x4E6074C55C48ED06,0xC9724584536808B7,0x08B34DC39944A0C7,0x7FD8F36F2EA8CC52,0x9EEF543EE80052AD,0x0CD31E92C801A9F7,0xC29F177AE19F9CC1,0x8D9EA2D593444A7E,0xE886F43D2548D27B,0x9E8FA20EE1303B7E,0x87D07BCD76601EF1,0x4F6F7C2307AED4D9,0xC0BA1FCB3F1808FA,0xA8A6C1E9499CB561,0x94E454E06187ADB0,0xA78A3320EAF675F1,0x5E3FD5D618820A47,0x94D7F877CC450304,0x4A6AEFED7D3C5410,0xB02CF5A79D016890,0x113C18E8539020EE,0xEB8D14B3663BE59B,0xE1488D11B5592F24,0x383C2B58EEC02FAE,0x48FA6028ED56F64F,0x571384D599A04325,0xF8B15FEA2EF4CE3C,0xADA0AF89943EA8E7,0xFBB80F9DAC3F55B3,0x6E99FE3E045F705F,0x9ADAD94682FEC6D1,0x5B6D283ABFA1D47E,0x0E1126A2270B5064,0x30585236C23ADB89,0x50B8FAA04F8B7441,0x3DF79B61377C937E,0x208D394D36D5A900,0xFEF31145F20DC6C4,0x8695BA0799E27F24,0xB18ED66525CA503C,0xC1B391B239A3C38D,0x8243A139CF172CD2,0x3EF4680FB2B6359B,0x147AA91AE44F079C,0x25A3AF9FBC025EC2,0xE3ECCCABAA462792,0xD71E2FCCC2D509AF,0x4A97369A9E16BD6F,0x02B14671EF71FB91,0x771FEAEF7ECBABEE,0x609CFFAFA96AE396,0xE846A52EAEC0442D,0xAF124D35F50458A1,0x84C87BFB90F3119D,0xCB4D592B4FCF344E,0x6B4624037197BC2B,0x6C4D897DCC91D7F5,0x565F05D3BA45BCCF,0x8B5BC52482B29F68,0x7DFF36E862A65D75,0x17078D84EB8C239C,0xF0271A8516667B96,0x567E731A471CCD0C,0xD2D069616186A55C,0x8ED941FBA09FCADC,0x483408E54BC504B5,0x6051B12A1F5E5445,0x601F8004F6CA523C,0x1686A437486D03F5,0x4C7EEB9F8B22BB7B,0x6DF4CBE6C725729E,0xF314DF040FECC154,0x19DCE34FC933A578,0x4BA606545EA8B038,0xDDA8E86D65F76B46,0x8F21BF34701D0FEB,0x078D13E9BA838CD9,0xFCF2F191F23EA066,0xA69818A86C3577BC,0x0693BE5F5E71F9F0,0x9B18E13681BD8197,0x743CD22999599586,0x576C8B3BB4C0F307,0xA2D8552FD52D5D54,0xFEBB453886370BD7,0xA473C6F37FC20417,0xC3CE147FC06BC59E,0x055C0EBCBA47D956,0x201E183D294B004A,0x1607B643A17F3ECB,0xE1092094D460CBAD,0xA7E9831F10059C4F,0x30C4A7A92479E33E,0xD6C552EF000736BB,0x70B20E6995691CA0,0xA80D50EA563A2BE6,0xAC3BE31C6CE51770,0x305800669D29808C,0x416FA9EBB2032766,0xEF7A7A09141CF523,0xA3DEF790F9769395,0x2879A36C475D11C5,0xEA3B5A712D84FC74,0xA8AE677E1BFADFE3,0x89294DAF28FC929C,0xDCD7E3644B8E557C,0xA8A6E10DC87850CD,0x5A297896F352ABEE,0xA0648009BD728A35,0x19643965A663F0C1,0x6A821BFEA7834CF8,0x4DF9615F7BB0DABC,0x84E533A5677B40CC,0xB3E8B6E685AA3FFF,0x73215F578A6026A5,0x14606717921FCB06,0x9A5B4FECA239594A,0x84C7E425F6D781F7,0x6BCAC6BB09EA14DF,0xD95B8769D0875DD9,0xFC53DDC748B2A59A,0x8B6D99339BA77908,0x8A563FC323A3F159,0x2E8CBE72F4E9D23F,0xA85505E0A494FD47,0x577D5B5FCFF97643,0xB16747979727D619,0x23E14C9E00D60FC4,0x3F51BD372C29A4AA,0x724DDBCA55098D72,0x537584F21992AF32,0x99A99E61612C1207,0x24DB2939783A09DF,0x7E850F1A5F3CF75D,0x52D33FFC8CCD6E8C,0x09D090A86F721780,0x8D13203AD159A94C,0x8E851B7E48AF2CA3,0xAB586028A6E0C6A7,0x03F3CEB41D6C3256,0x3EBC6CBFDF9154BA,0x7EC68DF3BD796480,0x9380D3272F9A8D83,0x642576CA771326C3,0x192913E2C0BF683D,0x026D3A2FED15F0BD,0xD649D1C5AF804539,0x7560F4084CB086E8,0x98AE8BC06900C1F1,0x9F43A1CEB636C8B6,0x1C20C20FB13D0CDF,0x9746F41CB7EAAAF7,0x37ED3323A7A34B92,0xCBD540C5CDC58045,0xB50377CCB42A6B6C,0x0E58CDD37901DA9C,0x4CC0075ADAAC66E6,0x5BA1D7B8F7BCACD1,0x735C7E2ED36A1895,0x65CFB533D977D95B,0xB22D1D883E78914C,0xBF0803A097F8B786,0x689F4BAAF7B50EA2,0x063D573520312036,0x4BBE1F8F8E568288,0x6B4BA7564870409D,0x10648536D1218669,0x76B7B5A1B3EADB80,0x6CC561474771065D,0x25124FF3FA3B1E54,0xE3954C4BF1C736F2,0xA0F222B484607DA7,0x79B928F295A74E4D,0x443EEEF692D8243A,0x10FD0BD212E93641,0x79B92540AAE45511,0x9269FED2CE5EA497,0x2EB83604189A2CA0,0xF342088665A91586,0xEF1FDD555FBC11E3,0xCB9B6FEDD1E877A4,0xBA077EF1AAA65799,0xE2369D942BC1E56A,0xF7AD0788A25C90CE,0xE1DCB1FCD76DEABF,0x25AF1CFEA479A178,0x55C730CCA9F1BFB1,0x1B9D64B1FFA4E12F,0xABBB8D6E8ABFAC13,0xFE011DEF7C082CF6,0x4DEBC9CB3B417ED6,0x7E1914473B2A05B9,0x069B9484512D09CC,0xA021CD7812294915,0x669CDEEE1E6BCD6F,0x702141DB468FBA8B,0x470227BB0851D665,0xD87ECB185F4EBB59,0xB77B94D6076E57DB,0x34AA299755EC816D,0x847EEC66C5218A0E,0xA612AE4258D9ED13,0x6EA92E523D091C7F,0x001926B93D132F55,0x16F079EFCBBFC8FB,0xB53C310EE61EFE44,0x02839DB6CDA704EA,0x18193A153720D3C4,0x62A390290DA90D12,0x0A45D9E99C451486,0x9E7D953E50B909FB,0xD3E2227EA15139A1,0x0187E97554821647,0xB7FDF0236A9B2323,0x772A46BB9F132D20,0xACFE1A5C58A0D1E3,0x097AC0F85A42824F,0xC1F4208F0C369CBD,0x7188030DFA59D49D,0x8B467F4C7CCDAD66,0xCD1E5B1E0CB5FABB,0x7AE6E073CE5FBB67,0xA67E7E152705DF16,0xDF29D438399029C4,0xDC70A5D9E6E47234,0x5BD6DAC8D1C33D12,0x4845E8ECF252FEB9,0x5A4002D337187984,0x68882301697CA6D6,0xBCF9DFB9C7392D18,0x5F7C01C8475C7F21,0x2E70F1C065A0B70F,0xC876429EFE6E455F,0xD363FA39642DAF63,0x48119C601087DF28,0x3CD89B8CE064AE26,0xBCC07DDB598379E7,0x9A25E9A61C28807D,0x50384E88E56F47D0,0x09D0AEE18FF47513,0x3EC989406A1BF525,0x578311E787C02A10,0xB587D97B43F2FE74,0x27BB099775DA08D9,0x4A9A8433A6484DD6,0xB2EF399ABB64195C,0xB3B22622AD08FBC1,0xC7934ED5DD4EA8DF,0x332B4BEF69EB2542,0x42DFBF94F2ED918A,0xF54D046F5A55AF1C,0x2A7DB08D5F9E6F5F,0x3DD775B07BA32A77,0x44320BD9B41737C1,0xD08FF7E0C9C551AC,0xA2AC657B0C86C046,0x05A2E7E50EF20CF3,0xA1AA83C89306865C,0x27DE875E9A5A9238,0x43AC33A8F3E3D4F9,0x2853AF74C74945C0,0xCD06B7D2903FCFD6,0xE7288B0F82034AC5,0x13AE990C7C17686E,0x2D5395A39E1F2C86,0x5DF80533AF13A27D,0xCC7DD6DA940409F8,0xCED1BE5920D1930E,0xC6993A8A8C533CF6,0xBB1534086044F358,0x4AD1FB381E661AA9,0x79E02E33FAFA9241,0xDAC395706DB9EFBA,0x2B122BB978BCFD60,0x24D7C2BF6464BF98,0x86F313866181A09E,0x841CDF9FF83A2C62,0x57D2DC92908D2BC6,0x1AAB56DB47476664,0x78E86481DCD3C724,0x8C3EA0641E5E0727,0x72E522E949C60279,0xD6DBCB371A595A19,0x49B270DEF70BBFE9,0x1493A9F75DB316EE,0xAB976B6B9162565E,0x0F4B102ABE5CC592,0x564BDB991DDA8DB4,0xAD55A09205A333AC,0xA36BFD43A0C2D7BD,0x58B7C211FE19D559,0x7195333842AA2404,0xAACABAB943F28B04,0x3ECAA3757DA66D5D,0xEEFCAC6BF65B42B8,0xEBB516C62BBC026B,0x26F8AD03FF125F1A,0x30A13A09F0D00DB4,0x1A0EE41E7AD27157,0xDB2C48B50BBEF29C,0xF7F5A0B1176FF18D,0xCD290D1971FC3B02,0x570506CF0BA3FAB5,0xCA8DADE5AC6A98B1,0x433215F1B66A9B8C,0x8C77ABF137B66BC8,0xD7EB503DF3114DEE,0x7CD31EEE2CDE31E8,0xFFB51F0289879EE8,0xA229BC18F2E7E46F,0x80FB78648F886511,0xC4AF1A7E84E28845,0x288EC1386F7EDDB8,0xD3A8C33A9B526E1F,0xD9C3E7E32279FEFA,0x300690ECF73100CA,0x8971DF85EAEDB0A6,0x21B9EA847D4BB330,0xE401A545EBC3A276,0xE21120AD8F394E2D,0x50E5C0AD4800F2C6,0xC03F9FED6447C37D,0x5030A9A11E6F6554,0x789FB4E7D79284B5,0x4C72ABF300CE9FA0,0xCE2966A15D145695,0x6D06207C30BAB62F,0x3BD90583991EDE00,0x86DB8B294716A447,0x64F8B73B0D17DD99,0x73D4586B76BFF018,0x13EC538B1F1D05AC,0xAFAD5AEAD3CBA4DB,0xF8A5A3E77BC65346,0xE89F2E776C74D59E,0x93DA8BFD0BAFD794,0xF1F16686485729C3,0x5573257FA57B5AA8,0x7E28D34290BEAC18,0xF4ECEA5D65077E83,0xBDAAAD2B9CDE044E,0x89F1D152818212FA,0xE04516C24CBCAF86,0x36D0E828CFDB456D,0x9CB164092BEA053F,0x967FFD4F6B9A3214,0xCF5C463E13DC78CA,0x8737A12EDEED2F2A,0x82F796AFBE66EF5D,0x702AFB6139B6A8E5,0xB7D85B506B6B3C2B,0xA36B20C46E6EB9D3,0x0A5AAB9097267515,0x4703B79AA482407A,0x48E34F30FD7A0F0F,0x2CDF1C7733B688C3,0x87E0014B2178146E,0xB5969342CEF4F6BF,0x36F158DF8C2D8C26,0x74F97CF0B9CD668E,0x77F94D151DCE0B16,0xADF29A522ECC1BCE,0x06F4D6B221BF3FA3,0x50A93CAF25499349,0x8CDEC04E5BD67711,0xA6E55CE74B5A1A0B,0x9665E6AE7091E85B,0x1B5FBEA32AB8BF91,0x1E76F0888D3E0D51,0x296255E16E6B2CF9,0x9377412B5C6B00D0,0xA70646166290D1C8,0x25C45216EB1F2402,0xD4A36B7320D30BEE,0x792FE47A3ED48DA7,0xD3E86A076F746C97,0x69925A7960ABB64B,0xA8A207F8C652A266,0x0A38ABB2244D0572,0x3D6073D66B7A1471,0x13B8EB7AA4200900,0x4ED88D6C38E3C18D,0xCE3B56769336415E,0x0B0DC33E689305B4,0x0AFFD7E4EBC066E1,0x6CDAA62B69566D33,0x3A518078CCCD2273,0xCF5E1008205B90AC,0xCFDF1112AE083BDB,0x73720D35C64A5B8D,0x755347D7EBE93A91,0x442D257AB6AB8D5B,0xD828F10695FD503D,0xC26FD199AD8A3B42,0xF502AE416A3E9F13,0x5DA35E35E88B950E,0x60145D2F9CF5066F,0x7C0C455D42A25AF5,0x97817C05FEB13C29,0xC4E8F90EA06845DE,0xB0E2A4B0B2345243,0x657C9122E17F2114,0x24F9A36224E6B581,0x2D30F98A5C6E48B1,0x5A3110A27868E0F5,0x97E61A3FDD013632,0xDAF6E4140363CF59,0x42BBA256E1FE239A,0xC4837EBD41671575,0x66C29911B1E5BB87,0x5B512BEAF41E3594,0x470FDD511E2A36A5,0x6B8744E43AFC5800,0x2D624E6A81311410,0x4476CC35E127F206,0xD479FF8BCDF7295E,0x0E9EF165CD46F5DF,0xC8D5FB4532003232,0x18D8BD46DC7EF12C,0xAE9329B7D74BE7B4,0xABD3A5B5DB900F92,0x07D98CF0C7C75779,0x3CB8E9DFF9BA921E,0x091CD8510F066572,0xF02385E7AE0B34F4,0x5033594256BC6C7E,0xEBCE650F756B972C,0x9E5CAD5113BE5667,0x7CDA95F3F43CE949,0x658A411F74CA4D45,0x43F83657B143085B,0x87B7B4344A6461EC,0x526A7310862E0C59,0x7E3193594B4FBCAF,0xA4420C4B33E3FD1E,0x40C2AB9BAD1AC674,0xDA2A6D3A72B08E50,0x09CB63913D9AA4B1,0x15573A52A18F71F1,0x1C48BBF12E159E99,0xC13C6D9033453364,0x0E72523E5C87BE1F,0xDB8202FC3AE6792E,0x4FF768CCEA0F9D83,0x65B921439C1B45CA,0x5EF13B2A0DF70AEF,0x716C33A3BA9C6DF1,0x5CE64E0D92160BDD,0x3F783951A46A82D8,0x4359DE7F3C34A617,0xF0238ADBA055A5FC,0x37FD2072984BA9B2,0xCBD147DC9A9BDC00,0x619C84E02908E4A0,0xF034B4CE7FDA0BF8,0x993A61FDDB6EAC0C,0x74D1B074E9AD1BA9,0x4E0B6E9A8244600C,0xD2896776BE382765,0x386D3460453FB84F,0x45B747867AB92D15,0x02BDA994DCAB203D,0x17C8B3B549F9FC25,0x3246698D36181212,0x93E86304EB9F7826,0x8382D50F6D22D20B,0x988689ADACEBBAB6,0x76C66E3F3AC18811,0x6E7C120EE1053DDE,0xF740255CD4F23AC6,0x3220F25FD766291B,0x422515A42974F82A,0x6D5BA87F0F8416AD,0xDC58A85A9453D377,0xBEBCA0D578CD9496,0x8B82BE59BF75B647,0xA0132B6F75D5D26F,0xE499E68C86CDF9F4,0xFE740E9C87475F04,0x6852A1EB08D56247,0x20B1876F1D0A9BB5,0x6006E35D1137983F,0xC5D874A18FDE0DBB,0x2B9299DAEEF1C523,0xF8E920AA269E12D5,0x11A12095FEE8726F,0x4EC03869663EBCAF,0x01667288E6474485,0x5C0D44B224ECBAC9,0x041814CBA6F921A9,0xF986D51507C74F4B,0xE77BEC45A2C7593F,0x62B71A6CF15F2C55,0xA06526CE8DD0A23A,0x46281D8F91DD20FE,0x8C5FA4B9C571E1AC,0x2188086C28CB62C3,0x9A95DCB8F9343D7F,0x748B1CF2E991FCEE,0x9E1684A784C04695,0x97509952AFCADC72,0xF69BD13E0E1A15A9,0x5B565EE535FB9064,0x6BB6598901655FC1,0x5E5BCE29ADAFEAF0,0xA4DE9EDB5527E628,0x455DC4D11514422E,0xE38F3F54F6BF7F9D,0x0EA31BCCBA74E3EF,0xC8A777DF8195442C,0x636CF973DD029C98,0x4119E35E746FA18B,0x85D873148CADD811,0xEB419FB35EE7F941,0x6B25222EED745DEB,0x4AA405875A6EF262,0xBF865F54FC9985C2,0xE8636255FFF77949,0xE035B0FA1B1C7F42,0xCE6F526DABA8C66C,0xF2270857346054C0,0x41268DB0A70B898D,0xE1BA065C832C1877,0x5E9ECFDE66C5C4A5,0x4D209EAC11973BFA,0x5BF8B35FA6359718,0x1B57C4DD9A9F9697,0x711650AF565A661E,0x7CE67E7B3728E7FE,0xDF47D05E8B7F490E,0x9750119456B05D09,0x5B6A9FB57BD3BD23,0x56F15DDB0E4EF51C,0x99C713E37798E70E,0xAD65072A72395DA3,0x481FB9FE2D7913F5,0xD12F6C98104D1587,0x3214BF7F51A3B55A,0x8C59A9B60BEDC6DB,0x6C954C6E521C7511,0x5946F5C6F5BED667,0x93BC7B8565746B54,0x9AA40CCF30A09F54,0x46FC12A69EC9ADB7,0xF53748B1B91E16B5,0x7BA9DB1F307CE2F4,0x5C515B6F3D0219B2,0xB49CCBDDAA163043,0x7F6E04E7D5974BA6,0x0347D8C9FF87D4B5,0xE28C53392EF2D942,0x652A0ED29CF07014,0x7FFA164741C9CB62,0x586CB2E6318DE07F,0xFF4738DB7992546E,0xA19A24635A518549,0x3513B1402590156B,0x97E6267FC93D0F8E,0xDEFE4ED3A3D37B0A,0x7EB4CA33EC7B9A10,0x4DE9412C4A004683,0xD54C6AB32210D803,0xACCBEC1582CB717A,0x24F6A387E5E5E587,0x61AD7C306CADB8EB,0x5C9BAFA355E9EE89,0x7BE501E8F06DEF3B,0x2E63D7AD80826A6C,0x2081DA78EAEAFADE,0x9C139564F48FD687,0x5E7E1087A3D87C48,0x9FC4330CFA3679FF,0x63A268C64A38F3F3,0xB389F8D997D41788,0x51D1EFBA767DCB93,0xD466C2ABF000E40A,0x7386FD197A67ACFD,0xA799C1397B56E326,0x849B0A441BBBA06E,0xE4062D202561689F,0xB78232A81BA3A332,0x17D91D4330F6D029,0xBEBAD2C90FD01DB6,0x3A923B297643BF86,0x7FA0D623F1538821,0x4B56F337FB664943,0x85101FC6BD71CB5F,0x59F4C9435089D7A6,0x73C848E13938B183,0x4F2532BDACF56ADA,0x6A4702B86163E9E0,0x2140862CFAFEEB1C,0x49BC840484C9D93E,0xB7B4B1914B0232B7,0x835B80195A09CC46,0xB015C81AE73D3492,0x5BD50E00CB10767F,0x68D9E537D11BB3C9,0x996DEDF5486CF60A,0xE30333DDBE22C213,0xCF62096064B51BC3,0xBE8EB4F9FBF915FB,0x1AAF4C748A596311,0x0D5322D1DFB7518C,0x9EBB398975E99975,0x7A5221F4378E2C87,0xD883951AEE05A31E,0x5ACD33C15E02DD40,0x6F0ECBDB32CB1A8C,0x426ADE37E7245903,0x7646B6B49745DAC0,0xE597500037FD83C5,0x2D58FA3DEA1D02E4,0x4B781B68DDDEBFEB,0x2DF7A7C86EF4AF47,0x1D0F28DADC303056,0xA7721D023B9AA4E0,0xC52EC6CFA9B1316A,0x4BECD5DBB7EAA735,0xF579C759BA0A7AD9,0x6E130421168D6017,0x33EA9F82337A9371,0x6213684BA142C94B,0xEB1CBD169625795D,0x0E224184C67FA35B,0x664EE78E1F4AF3BC,0xEB767EC4B3A543EB,0xD1FAE0B170B3DDAE,0xDEE1DAEFC6A24918,0x50083F8FE47EABD2,0x6C02E815D7B433C2,0x06ECF14FE314C853,0x22094E35C58AFA85,0x141B9EDAC01F6C67,0x5426159B55940616,0xECE038EF67632372,0x927B47F34A96282E,0xD82AA464937FC49B,0xE68F90119CA97046,0xD77FDEB8D00BFB46,0xF5A24491B0DFC527,0x24F2B82032DFB696,0x99D888062EF847EE,0xF011AB21A3821686,0x4243A94ECB276DD4,0x4CAD503912E4250F,0x9CF6C51EE688C207,0x95938EA61E9388C6,0x2EBCFC20CC806D45,0xAA81776CB3436655,0x038618906DEABB05,0x5DB7CD6166A3E30B,0x51C38438B0799FCF,0x1C134057499ED32E,0x9750188099C266C8,0x93C2B8F786847C6F,0x132F4384A482927E,0x42F515DE0978CF98,0xB354232CAEFE70E9,0xD49C0C30020A91A6,0x04C2A40FD0AA5FF4,0x9B3F59874B74EEF8,0x2C61C59718855ADA,0xA3945B468F01E8B8,0x28F3A43E277690B6,0x0E6AC136F9A670A9,0x0A3F7584AE3471E3,0xCA2CC22FAF5B347E,0xDED9F19FF1C8A98B,0x5F7B3BA58D4F33EB,0x8FC26A4F37326D12,0x542F08E8C07E5E12,0xEBD4A9C248BC46D6,0x6A021E9EE33401BE,0x5ACDE3B4D3D953CC,0x44B061DCC01C937E,0xDC124A530507E41F,0xE0F5D7986828DDC1,0x0C94211D5E46EAFF,0x652BBB444BD1F8CF,0x286A1E55EDF96168,0x67770723B6D24C2A,0x58F43AD6061FAD15,0xC406A564DAA02AC0,0x415C037F7F5B19FB,0x12753BDBD094CC63,0x672255756D7B69F9,0x9AC105326422B177,0x3FF8C683DD90619C,0x51FAE8702F9E27A7,0x1C5C8031860A92D2,0x547111339A2F0AB2,0x8642201D1E19E5B9,0x267891C7A1B20200,0x09B1843F753A88BA,0x8A0D2C63334D2E1C,0x1B10139CBD26FC95,0xBDFBAED4FD17AA22,0x52E4FA178EB7AA73,0x46F9E054580C387E,0xB9B5B34B399EED2B,0x70CB8507BA18F9F0,0xC4A7C63D7FD7958A,0x3DBAB032D9579B61,0xE23E8EB28D678755,0x709480D693D84AAF,0x999ADCE8C05D11A7,0xC4D5AA8DADE43162,0x271CA8B6B059905F,0x5DF202314B940E12,0x4EF318B64F8CC847,0x45115E7444F3392E,0x94221047497646DA,0xD7D0A419692A7FAF,0x647905F3B2BD8A5F,0x2D43A0959DDA3BCB,0xB6DDEA5577BCC262,0xD442D3B3F2AA57CD,0xB120ABDA69EE781B,0x1F33167D84609D3D,0x448C1D72350070A7,0x0B7207F2508390FE,0x59668340EFDE16F5,0xD6E16C10D400F2DA,0xD76B3E19AA0F6989,0xFF348688CC979937,0xC096218DEABED858,0x5500161336C38F01,0x71261E28903C011D,0x52BB0E71F2BE3A6D,0x3E53658E2F77E00D,0x8257BF932E18B009,0xD23C8775A53B529E,0xDEACE387CF943197,0x2ECBD75331F723A5,0x90E8D38982095B01,0x871094DD71651141,0x909DA4AE7153D27A,0xD892D6546D57FE40,0x9D636A4522573CDB,0xA97A0DC1D80EBD0B,0x41F772B1D2C24DD9,0x4066A3BDF3EAEC40,0xB62F39AA28E48741,0x71E6F89B57D6B6C5,0x16EAD21B5BEF17B0,0x1E86557B84309596,0x58778518F6C4DCC2,0x7A08DB5AD0481464,0x4D3F96C74618727B,0xB143E78CFB0CD739,0x74CA6A7F909E6601,0xC502B42F4A68A2B5,0x2AAAC825DFB6B7C4,0x3F1784CCE8E9358C,0xD542BBC58A86ADB6,0x4D002ADA91F234D1,0x1355E52B35F228CD,0x62ADAEFE4250FC17,0x211086E01B1618AC,0xEA304C7D4829AD42,0x422D2FD9B87008B2,0xDABC6F5C940F4EA0,0xD314BF5819E60522,0x1272D1C74FFBDAB5,0xB416FB9031FA4196,0x316367E8E9F9CF58,0x338746A01169ED2A,0x29F764F0051F3CE1,0x9DADB0361E7925C1,0x8B51DF8DCCA537B4,0x9E5B4B97F192C683,0xB3E213F73F1AC5F9,0xB9649BC6C79905BB,0x19B1E6D15875ACFC,0x8EAF811C9BD974A6,0xE20A22EB1EF5DB82,0xEEF04F82D64DBFC8,0xE4BFEEAD6932133C,0xDFAED0E3E53C3285,0x8642B47AA78FEC2D,0xD6F06C3A70C94E65,0xBF105105C4FC2EF5,0x2CECB5DA87ED2F9E,0xE733BB097EEC2736,0xFA626944076F6A47,0xA218DA3793B68528,0xE1C69945D3F85306,0x6A4BCD89F48C6526,0x29738F2C23887BD6,0x7EEB584E85F2C1FA,0xEFC91A3AD0A2706E,0x443214E3A5B833FF,0xF4D18DC0BAD2E3F6,0x29FF3EB51E5C1DAE,0xF59113DB141D67BC,0x4BB510E7A32FF06A,0x63A58B128B13AF44,0xF4DA37B86FC114C6,0xF9DC7134329BF4A0,0x48B746E4E00F2A17,0x12CFCBDBA552044B,0x2F98249C93A19136,0xD408E6E0A0F9D46D,0x7D2408A41BC3D171,0x468FB91BDCBAD848,0x365E89C633A20E3C,0x350F50174D6914A0,0x4833B55677629A53,0xF62E9969F6348454,0x906313407BD825C3,0x4070A789C0487873,0x2828652F3610B7DC,0x317B1284D684117D,0x6D768925969DC85B,0x63554E90AFB06255,0x37693D19ABC4AA2E,0xCEFD13D96C153835,0x253449B086D93A34,0x0227961312DAA2E5,0xBBAA2F90A1FD878C,0x8BA46086BCFB7F22,0x4423FA264DEDE583,0x4B19B2AEEE39EC19,0xD44DECF912C0449E,0x84A6C69E0682FE60,0xF77E5CBA46A0EC9D,0x973192EAAC67B3DF,0x6CF54EE242F0E877,0x6AADDEE4D720EE0B,0x0F05D222855C3C82,0x1A778E37EAE31E9D,0xC9ECBDCFECB5BF70,0x65C61D06ED8A72E5,0x93279E6E1DB0EB56,0x70EAA1384A98B59B,0xCEEC2AC398FB2058,0xFDC50008F38E6A59,0x4E75B5D209211EAE,0xD8002595BCA5FE16,0xAA4CA0E87B275A3E,0x59EE6E369A55A7C0,0xE9DB5AE4A975FD2F,0xFBAFB9A8B13070D4,0x8FAC7D1F60D33582,0x3E229ACD1A0ADAB0,0x0F376180CA2B4A94,0x133AC1F7A1150852,0x1905CED63063D873,0x47D231BC818374E8,0xDDE937B91203DC14,0x858A799A4EC07197,0x58D7F5B2A3BAF9CF,0x92A011043AF0ECD8,0xC64AF310F2016257,0xDD6EAC5EA36F6119,0xB2028DD1283665C2,0x81F8BC7A5A70DA11,0x9DFEF5206A36988A,0x72E2CC6C1FAEA629,0xC0FF670405950F41,0xD79AE6E1DB6C46CD,0x729A4DC22BB23E60,0x7E056ABAA8C704E2,0x6E2E9116C56275E7,0x960F4A69365BB251,0x66F249B233878AFA,0x974DD24A73EA8C52,0x5ACEC24A09A3A1EF,0xF2E25BB138FD84B7,0xB0E2F076AB2C5AD6,0x330558CA4E7DB8ED,0xFBBB17B42EE59222,0xC8FFA1108D7EE165,0xD77F7080C12BEB8C,0x5E00BEDC2C3FB429,0xCD2790A3F9CB7245,0x7A2D5F446C28E569,0x487CED7C289E2614,0xFDC12EC24713D4D4,0x35514BF58D04EEC7,0xA569D4B0C9A060B2,0xB12C5E893D8224E9,0xB827E46DE671059A,0x02DB77FA8CB10B51,0x8832C1E142F723DE,0x35195F5773ED8656,0xC0028020FC959D6E,0xBBDB5F65BE04EDFD,0x6B394545921BA5A6,0x9B97BFD02D5C0702,0xEA122C48171F8DFB,0xF80E97053A3C2440,0xAA17C28030317AC4,0x254357C6B3C1917D,0x84CECB7F40537649,0x9CA11829403FDB1F,0x3571A2A730C67F6A,0x340ECE696749A915,0x42E91E3200CEA8B8,0x9B77DCBDFB7D3A32,0xE49F7F1DED21049B,0x095A7655A80AE8A7,0xE1ADFFA411B0A05E,0xC20CC60B548BA935,0xEB9CA48F738EB342,0x455D76CB44531833,0xE1EC56C3CE9F46B3,0x67FDC467ADF05AC0,0x19D64644B58FEA9D,0xC7132579447BAECC,0x5CC78C0E54CF375A,0x2CBDE8F5C4F2EF53,0xA5F5F6702E995B82,0x20C42548F0E7F6E9,0xA3D926CA4A6BB49E,0x91FF593F1298CBB5,0xE4C81AA5748DB472,0x32A2AE8408C4FAEE,0xEB3E598AC460839A,0xA303DFADBF3A3B18,0x9E9928206C824DF8,0x46F296413A473B91,0x60ED11865862D8DA,0x6BA0C6E08214E977,0x541E0DDF5A885DC6,0xD65B3D48002780A0,0x30857AADC7575471,0x66AD7CCBB4BA6798,0x5BFDB2A3B0881FB6,0xBEBA4D50E79D6B7A,0x0D5824107478FB2F,0xFABD82CDE36DB6C0,0xA4C2B032BB0BE071,0x89D699551D903921,0x3BDEF7D9DD4FD486,0x305C4117D8D57BEF,0x54D457752B090E3A,0xA83BE47CC3828F20,0x8A740A062828F927,0xE156E3F5C55479E5,0x42629BDE4EF3ECF3,0x3C9D0CC01B96566F,0xD886E47D4EE19E96,0xF483B39A4F8C71DC,0x9E80BC492D142BE7,0xA663F1EAC88FFF90,0x054486ABB08BF34C,0x7B8D7C2FF74DD5E8,0x26AD6E03561029D9,0x4FA5825324D1E08F,0x0830C2444D27A78D,0x81C7EE1A4E73200C,0xDB1C06874B5E23D7,0xCC98985345941C6B,0xC8EEEDEB808D0B6F,0x8057C083DA726E2A,0xA212ED532F8581DB,0x17C6A828BFEF5D3A,0x55867651029BC74A,0x7EDF618AAC05CE99,0x2894D6593A577B76,0xF170A99479A364BF,0x6554BDD2EA4786C9,0xA897130917004275,0x3CF9756DDCF9232C,0x9B6417214C615848,0x17E4C10A5A9C9D2E,0xD5632B38A6257FCC,0xAB828251C5A4462E,0x46CD85F095BFD878,0x1D999751D06C7311,0x73C6F7C4F8AA1C2A,0xED046241469E220C,0xADE13948E9297EB3,0xCC470AAD32D36FBE,0x9A636F84305A5E8E,0xCBF4DDAC56ACB7F0,0xB13272F701C03517,0xE3D884BE3DE0044B,0x386E0EA781243B9D,0x35D59D38009E6EBB,0x46911D15D92F8AE1,0xDBC0E07A37318CE3,0x35C43312E4D9ACE0,0xD915FD77C8E619C0,0x7499039AC1630481,0xBCC76F5F2651BF3C,0x62D370579B7CC296,0xBC391C3DC38DEB3B,0xBD1AA451E461082A,0x48BE27ED5E2F3770,0x46F9B86BE9B770DC,0x55EE78327DFF30CA,0x7AB039AC1F95E355,0x535192F1986FCFF8,0x813EC3214ED46CF9,0x3E88E4F0AE714D10,0x3F0E416423F79F92,0x82B6A3D926CD7280,0xA3E00F5BD594612A,0x36B687BDE3566063,0xF1B750D411F9E2FA,0x1C19EEE7FE48A4C5,0x7B41BD98598A3203,0x6909184CF9C17F28,0x5F7697F7CE366B22,0xED5A2C42A7211CD2,0x09EF2AB2DC073C3F,0x9D408B38D0786E13,0x6245B2EA5B4ED999,0x925C2227D77DB8EA,0xD36C02090281DD2E,0xF550EC6501E5F77E,0x583F0548F7CC17D7,0x838452BA09F0A07D,0x423E5BB7A3B75584,0xCF72C5929557BEA3,0xF5AE1505AF55B594,0xFCA2E423A5061E6E,0xA8E4A5C00A273DC5,0x1DDE3371CF295C1C,0x3CFE2CAE24A14FB4,0x9A49567A6A6DE44D,0x120142D86A53DF35,0x5F7B414AD7E4EC46,0x0726C40BA98244DC,0x20D9EACFDC2CB4FD,0x4E5631FFD203B254,0x1543D1B808610ECB,0x71E45DD7FD95F5D3,0xED97C0569DC4C14A,0x1350DE634269E750,0x79150C486065E691,0xC21DB5631EDDF2B9,0x9DEF3A345F332091,0x30118EE7DFBA1D99,0x766B71396FDF97D4,0x22801E0AD23FACFD,0x0D1EB863838CFF12,0x2FA0ACA001ED5D14,0x96314CBB9C5D257A,0x056E631430DB58A6,0xD213B4F9F02C85E0,0x9A7CA9B190F0B5C0,0x282CCA016ABD678A,0x2757885DA1809AAF,0x8DFB4761A51DFC3E,0x1441A649C617F7E5,0x9ADCF8ECD6240F16,0x689205672DEBCEDD,0x22C25F6279EA5DE9,0x640CE0097AC57CFB,0x2F27CA731FCAFAA6,0x9616188AD2502680,0xAD6140225272F312,0x58AA52AA922A6C7D,0x92A97B8A6EB1CE9F,0xAF0DD32887354D09,0x6AE117EAB5FC9CD9,0xD2A33DA627B23B0D,0x1C1BA785325E5D3B,0x79646251A8668B95,0x704CE3F6246D3ADE,0x18FA56D931B94AC3,0x4FA428C8F65CABBF,0xBF29580AFEDC17CD,0x149FFDEFF32DB10C,0xA3274F1C555EE524,0xC6B6A0FD679553B1,0x54FE979FA0833F65,0xFDB84D915A3DA093,0x269DDF29379423AD,0xA25F585838CC7E83,0xFEBD6CE721DB1123,0x269C87046CBE8F84,0x057CBAB4DFBF5A55,0x5D529F9D1AAC79EA,0xD0E4BD9631D0CCE5,0xA00C7DBC2C84A813,0x33D89A3D1D7ACA7F,0x5845085D2AD907D7,0x92BEB6D87C847D47,0x7FD391A9271BE86F,0x3E1B8D7A9200A575,0x1039176A5B92111E,0x9C2029E322D0903C,0x320BED247DAC9B19,0x1BFF7A60020A8227,0x7E9AB8C88351A0B0,0x0E58DFBAFC7BB5A3,0x2AA221AC4DA551C1,0x89F3E9F1288D2896,0x339912F301FA75CF,0xB80C3CFB568B25C8,0x95EB0CC7DBC8980B,0x8B26A0893827548C,0x613B02B9F85D0D3E,0x217F10FDA37AB4DE,0x1B15AA4BC6A8FE17,0xFA5EF066F39CD7D0,0xE64435366222FF30,0x64D8A9A5D54E12B5,0x2C3A9910DF45F962,0x498E1F39B4024099,0x1F46092E48DB1D48,0x2F5B3AC4E119FEDF,0x19312C99554DCB60,0x094119FE38C1130D,0x49D16F30F8CB6E9D,0xFCAFA4EB1FF32478,0x7C1C2A31D178BB3C,0x4ACB54C93BD61CC6,0x8B8185E3FEF464E7,0xB5DDBA8E431732DB,0x428C38343CA57D8D,0xFDC1A2319FD27452,0x7702F1F1A0FEA822,0x8A88EBEE5F0812AC,0x090D0200C6128674,0xD68916B583E90AF8,0x078D6D3EACC42C27,0x8A02A0A2AB11B2D3,0x4A73A087DDDBEC61,0xFD79F7940E88A86E,0xF86756D594E75C66,0x1279E0FFA787E2CE,0x77A13241F74C8E00,0x21470398154F4531,0xE63F4CB149813482,0xD30B201530782048,0xAE18207401E87549,0x83E5F8FB18C6A6EF,0xC08ACBEA197BBA7D,0xAE5B2F8B2DA22936,0x0C6805D9EA103CF0,0xBB730105D582DF14,0xF472A8E25DA62CC8,0xE25F4E4A27E21887,0x684FC32BB4144E92,0x383F54C228AA84DB,0xA0956BF5CAB4947D,0x388FF8C0B2149E6B,0xBEE2D042B7C6D711,0xC95BD0CC7B30089E,0xBC1D0007307724C5,0x262293B61D3DF369,0x997C9CA8F7A6071A,0x896717CC319258D1,0xA04D6F0C6E7FCECD,0xBC36918239996822,0x43EA18DB4E7DD480,0xE838A95A4782DA06,0xB448CCCEBA4B9042,0xD135B1B35D7F4C4D,0x2E79A175508BE133,0xBEB1B74D905F6C0D,0x83E841B86D42EEB0,0x8383A5C91B3307B7,0xEF8F165E5FB12127,0xEAC90388CD5204B5,0x6777257006B83067,0x6FD1080E494B87D6,0x7B8DB61A97A09180,0xB79C5CD56D1B51D2,0xA7E81A44DE6D81D4,0x4DDA293D1E852EED,0xF1C77F8AF247A589,0x0AEA1D18536EA347,0x528D5698B536D4B8,0x745CCC045080FFDE,0x8A3FC6FF64184B98,0x5990D40A9D973268,0x7DBECA1961F3C937,0x7419725B25F128C6,0xD63639AD078A3C17,0x826DBF218E58C182,0xCB653C459B5BC958,0x2CBF20E4B43A9E34,0x5679C1C8C96FC269,0x72A3E59F52A61081,0x7E8B2513936B0134,0x183879A6BDFBF879,0xE224CEB0286D2EDB,0x2D80D36BD2F2CB03,0xA62BC5E6CF2BE628,0xC54FDFB1B12CC667,0x4350A24153DC34C9,0x0D8088355A3A9A78,0x5587D45383C1B3DA,0xFFB952B563B550A5,0x44298E2C87613DFC,0x6B2C92F53357A26D,0x245C20C04291BE9A,0xCC18E28F2ED6B65C,0x63E82F1919428E04,0x992B75E3A3416EA0,0xC780B3162B8991C9,0xD3DCE8D9F9BF2FBB,0xD14970549F4D5620,0xD547C1C937EB657D,0x83857E06DBB004FF,0x973D0DCEF6DA8DB3,0x1107AAEC22B35ADE,0x3765B9D88CC3D95B,0xD3FD4605DCE34CC1,0xADB84B332B7F3037,0xEF3FD989267444FA,0x3F121D100EA902B4,0xF902CAD07326BDAF,0xD751C7CDBAA59812,0xAC77D81DA938C7CE,0xA7BB47D340240333,0xCACF0BDA42832A2F,0x2CD1090199874440,0x9FCA13AEFFC6EBAC,0xA47250B60170337F,0x7323C8B0987E8B07,0x4FBD2E45DA8327AF,0x3DE8C2925DC3FCBE,0xAD916C90A1166BB2,0x8A1B6F495DE05D40,0x9E400063527C8753,0xF4E2AD5838BDD344,0x6385C3BFADD75B9B,0x7BF3A7600081D8AE,0xBBE27B45C1F37361,0xF3C07F95FE3B8EB3,0x9DDFF34522D92514,0x52F3C4761108081C,0x877A3C2EA401382E,0xFC679703BA2B1497,0x63FB08C5D0516330,0xCE0F57B959F58959,0x95A5209BC1FB3819,0x26A3DE413336B5CC,0x53645D022BA601CE,0xE2CF1E8220760DF4,0x1B7C0DCA83B2A701,0xF9B840F99D9517FC,0x1286F18385146599,0x16E46D08B7DAB87C,0x557282786F52803F,0x54DE6ADF598647CE,0xFEE7F04B3D14D542,0x4217BB2DE34735EA,0xBC4E60F289529D65,0x0DDF7342D24FA367,0xEC9AE2CA36C6B6F8,0x77320578AD47FEE2,0x4033B9A1115F2F0E,0x937D3E5C72A7A1DC,0x289E14C8E50D80F7,0x84979937ADCD0898,0x6FA9A675E4243D56,0x9B9CB0E7CB52AF62,0x1507FEE72DB1C8D0,0x0D7FCE9A88ED8A0D,0x365DE6425F209578,0x84C1C2E36625A79A,0xAE23A4B2F7CB1DC5,0x0ED7A253878128F7,0x0DF35EDAD89C6CF2,0xA5E5113B90C262AE,0x39AE651883FDB620,0xF10F606E4B04153A,0xD5C83F9592C26EAF,0xF9359B63978F76BB,0x747F1F930DCB3AAB,0xB09D3963E25CAD5B,0xD710B13CFA81CB6E,0x94EE858B1D2C820A,0x1393ADE7C9460B8D,0xB3C6B5B5CAAEA455,0xC6B57B23CF458A5A,0x6C559415E4A2649A,0x088FB032355B3683,0xDBC44F19D5F92F45,0x4C600B71255EC525,0x92B2A33CADE4CD3F,0x97CBF9E37579645B,0x822405A85DA9BF16,0xA29476E314FCCD4C,0x02CAD8555DA3A31F,0x1669D7369403BB5B,0xD7F73203826656F2,0x88B51478A7F0AF30,0xBE4401347DCB84F0,0x4A38768C7EE3BA62,0x9E03E5284366F730,0xADEA24462EE13A13,0xF8773AE812B0F377,0x004D6A0E7BFBFE4A,0x1E6A34369276C064,0xA3A66FC8A7910BF1,0x5230DF1FA3182415,0x416C0C5F277F7A51,0x669BDD828383572C,0x74B7CB7B67A8AFBB,0xFDD1C02479152A20,0x619CF4F4BF350DAC,0x2AAF040C1C85EB90,0xC47750E0ACEABC38,0x4310DF7041D1D00B,0xFD273579BB0908D4,0x92DB0B26435F551D,0x7AB976AAA896F45F,0x259BDCBB3F286318,0x9A4ED3E0CFE67C8F,0x4F02B5A5030BA194,0x2045C91B1DAB7FCB,0xA44942E45EC22299,0xF0077C4AAD2C75E8,0x66C10CE69822677E,0xD2DBC4E2EECDB269,0x545DD12F23974476,0xC6BD1A9C9518226C,0x8ABA60CCD0573C73,0x4216169324E49893,0x1A1F3E1BF75AA660,0x1E6821A86C6A01A2,0x90B9BBFF2095C157,0x62C2E6C152712C52,0xE363945591200595,0xC10390F41AEA68A6,0x2C764B879643437B,0xFE3AB6E4CA36537F,0x2BE0C9CB26EB54F3,0xCAA4708F15E1F775,0x28C787AA9866929D,0xA13F5D9AA0FC5E5F,0xB59D32DCB7F67973,0x01E2DB9E009DB349,0xB2A0EBED8100D18A,0x7F9BC443CC65B723,0x5723AB2EA8207DB2,0x13D6F5A10C7F952A,0x386EBDDB8C19D421,0xC9F3429852539ACA,0xE3B782F5FD0FF49E,0x72C44EF3D944789F,0xAE580D1E6E3C7DC0,0x6E2E57DE68574F5B,0xCA74799936A62BA5,0x305AD6D7A0A116B2,0xA8826A5988662EC8,0x6A6CE6929F7EDE7B,0xF5770358F322CCF8,0x3C56066227971533,0x3AD8D33FAC780718,0x7B0ADFACF3070447,0x689A250C4AFB7690,0xA56B0F85B20EB3D0,0x1F0CF21BE2F535A9,0x4FFFBFA5F9BB216E,0x2A8E0BCCA31DD3CC,0xCE87F545F52F0A9D,0x5415F2AC71670279,0x5E5D6D00A652CE5D,0x741E83A5393EEC85,0x07583D57FBC1F3D9,0x6385F869FDD3B471,0x7ECDB08E28F6FC48,0xD54DB925227C7F9C,0x44B7BCA7F443043D,0xB1932A126DAF56A8,0xEA7DBD6A5D027938,0x3544F6D3DCAE4123,0x2B25082A9FDD07F3,0x41E2DD04B77A02BC,0x49FE142F15EF4466,0xA2A408D6135E4D96,0x30120976E1315376,0x0CBB57108C812B50,0x0E84AEE21852E0D1,0xAE7E7143C1741186,0xCC552096ABE23733,0x5D3874819160EE62,0x092CA4F0B868C9C0,0x51ABE9FBCDCF9742,0x1B8B24B6E554F89D,0xC5700EB998A73B00,0xA8EFED763B25FC78,0x53257E4B7476C807,0x92CEB246D469F90D,0xA251E29723FA665B,0xB0F22FCB0D4E1942,0xF046F87070337A95,0xF5599563FF335B18,0x711F206BFEDFD00E,0x7965E0223BB99689,0x4E0466196B6D40F1,0xE4E10EE4958A9692,0x3DAE304F27FD5D0A,0xA2B81687E8528E8A,0x58F8332DCED4BE35,0xC320ED6CAF87AF0D,0x635D3F57AF4AF6E6,0x4F6CE8C9DCE16994,0x2BCA03C2F239C0A0,0x981E3367EF11FBBC,0x3D114F92C55F077E,0xB928CFAD2FF684D1,0x35253B21130C90BC,0xEA92829C4418E614,0x22559B8D47FC6047,0x27F37591ADA37996,0xDDDE48F193D4F6A9,0xC38611FEA5FDEB9F,0xA284AF54B16DA0EB,0x5946EB544D7BDC6C,0xD747FF605EB4AE1C,0x1636897B9A995F98,0x3C658D07223DDD91,0x905E21A2C0E60A68,0x60CDF9F440CC9B23,0xAB05C4BF1603FB4A,0x2FE1E5231056CC08,0xC2E6CD337B024AAF,0xEC93C0F28F425CD3,0xB14FFC4EC90EA48A,0xD70570F215E3D379,0x3BB4A87C42785376,0x228C32238AECB512,0x96A449737CDAACDE,0x7A3FD34C22102952,0x6A5B857B61F01316,0x4F09D0E81F77050F,0x49F017612A643B2A,0x40481AA45E66EFDF,0x847F3E7964A71FEF,0x563115B2A3E76FC4,0xCE41DA91EB0569F7,0x66842A795842B83E,0xB04BBBB3C27192B8,0x26C1E9E986444775,0x1EBE9FA52ECF0E90,0xD994CDA4C96EA504,0x6D0F86AB14697696,0x545BF4549CA2A464,0xB0DF16CB62B41737,0xE6E8442DB1038460,0xAB14FEEF49E60FF4,0xA3026B34515F0261,0x9DA64F6FC74AB934,0x0261014139EA4B7B,0x07DCB70752F682E2,0x133E161C3AB88B6A,0x6AACCA5CF724AB7D,0xE818708849B3CBBB,0xAE26E5D64BC1AE53,0xCBB426D9EFB93958,0x40DC4B583A5356CE,0xCCAC375858B898E6,0x3ACD70495605A6D3,0xC9755211A3498629,0xD04B4F76B2C0008C,0xDF766FB1D63867A0,0x5AAA4260E28B22FA,0x3DC4E8584D2CE9B3,0xF487E03D7B5240D3,0xD81D1EEDB5FDF8EC,0xBDCD25BE8A7FAF79,0xDA71FC6B07BE1DE5,0xD7E9E02AC0C0990A,0xBC215431A0B0F7CC,0xA1F0DCA499791914,0x64831085056B1706,0xD61F6C810DA88F8B,0x0F3AA7345A736C80,0x18E35855058C6C80,0x2F8E0B67A43FF0C3,0xB985EA0BC46A2AE9,0x326EA4266EAF3B05,0x9DC6C4CAD12EF3B4,0x011D51F62AB046B0,0x35F2F4F1C4B38A70,0xC5DA48E0294228AD,0x1E5F8E32A100F175,0x89A8CBACB2EAE169,0x36A32E2CD6073E44,0x0B729DFEB5830E18,0x9CAE3837595CCFB4,0x2E1FEBB15B796180,0xE5695775AF846A9A,0x56B13FBDFF58C671,0x72FCF7AC96778401,0xCA6C9E9232486A9F,0x2240584D03650EE4,0x43C59A07C8A30295,0xDF590282E8463B61,0x05B185A729B0007C,0x702A39D839DAC170,0xD8F8979DC1ECDDE4,0x2A1C562C5B7A743D,0x79C3A9E6F129C1F6,0x9E485147CD9CAC0A,0x42D1DCDB1951C8F8,0x9902DC7D129EDDBC,0x8ED3F256C63B8042,0xC283D5C6853F25BE,0xB35C04CAA1CEC189,0xA4ACAE7BB4622182,0x9F627D5EC9F9C3D2,0x7045392DC3FBE5EF,0x980FE4B22A8615FB,0x1149D72565E88A0F,0xADFCF08131AA99AE,0x38202ECC45EC5873,0x70DFCCAC40F78694,0x6BA7A5224490D01C,0x7452E31D0A2EA09B,0xF5E90CF0DF38F185,0xD605928FFC42370D,0x027B0781ECC2DC93,0x76023D9E8DB0D030,0x7B9FC4C6A586051A,0xF83A30B1DA774DF5,0xF993A24EA33BB473,0xF2D21F5CD6D366E8,0x19358F1DF4E59BE5,0xA1FD2F0C92A8554A,0xE755739A0F3CF9B8,0x4BE3CCB841076C5E,0xE98EEAD0D42504C6,0x9CE038779D1EF17D,0x59FD21189959BED2,0x4190F07AAC768931,0xE0F61740A92E7F5B,0xD56D258C201ABA41,0xB398641677AF3AA9,0x2946C7BA262AE4C1,0x6ECBBD7587C9BE86,0xABF99E2646B0EDAC,0xDA124DC558D4A6D7,0x05FE67F003BFC89C,0xE6A546D70EF191AA,0x3F199383EA737A2D,0x4103C0B744B58B89,0xFDCA4F9AEFEA259D,0x8CFFAEEDB9B98D1E,0x8760F1EEB5C92885,0x15C51C52C49FEE21,0xB8BC3854D9C8A944,0x8768CD9B391AC8C8,0xF6DDB26D0CBC7C96,0xD2FC62CAD23FCD0D,0x0E66A36B738CF20B,0x188CF42F4C46DDE5,0xCD59753AD1A1F3F8,0xAA7ABED4E9EF4F3A,0x68349E3EE4343D29,0x8B15BB261A7B0F3D,0x7F4D3FFABE3F4C0E,0xB6325510DD7E5AF6,0xACF32A0F897E9A24,0xD1EF935B696FB667,0x165228E97B15FB69,0x8057C62AFB907C27,0xA841717DEBEC26E1,0x81622DB1A7E0FCFA,0x732B4CE4CD13AFE4,0x41EE385BF092668D,0x6E6B31C92A2D7899,0xF6EA071A6450E185,0xF65C05A2F41420AC,0x540EF2DF80A59E94,0x273A26180DFF4579,0x7ABC944113AE6DCC,0xDD3187843CB53387,0x96688E50915B5553,0xECE73BF4EA451B66,0xEB84DCF615229F96,0xD3019811A3CB36B4,0x9535B7458B0F982F,0xB4B2AF187B323F4D,0xDB3B22D4A3309468,0x255440F7027F61DB,0xCDFA0C81B16A036C,0xD1EA6A98FE77E2BF,0x70D3808D91D68BE3,0x0BA9649E31DF5F82,0xD6BA08A13E684021,0x65B1F1B44D302E45,0xEA0B03B2338C8D0D,0xA8E18E256B0A6F58,0x5785D95848275C61,0x28248857AA859833,0xF032291234A9AE0D,0xF5FD58BEBB8A114F,0xA8D7F815943AEF9E,0x3782D35F0B688AC8,0x7CF819E3768698FF,0xA94E5BB6F8DA729D,0xC7BB56FD5F5DAFD3,0x5399C67C335DACFD,0xAE2D4677F390BFDD,0xDC71C5E50E60153D,0x6293380A13DB0277,0x113FA358E265C514,0xB5F7FF1A5C6CBA18,0x8605C7E7CFF3838E,0x62A3F93F74302689,0x814BB73AF3683C4F,0x33FF1F9FF9CD15D6,0x2F44C80CB39F3C06,0xD3194B838ABE4FD4,0x5F6131F8D72BD655,0xE79CAFC41C041F2C,0x14123A8AFD7EB9DF,0x9503D1EEAE4BE758,0x2C0D0541FF10EBDC,0x81285C03BACA26E5,0x50B7B59088F80660,0x80AAFCF096F46353,0xE0F3945B92865AC4,0x674777D3280E6582,0xB9D736C24088E835,0xF8D4E1CF383B6103,0xAA11E9D6E5A7EFD8,0x6E381F37B31FBA6D,0xE2715C6CB14DAE33,0x1ABE58F9BF1ECA4A,0x0D326A352D73197B,0x1DACC9A1F92C3673,0x813DBEE8BE8EE558,0xD023F627780983BE,0x1B879E18D721B0F4,0x7DFD6D03FFD88B9B,0xB15E25D568908FB1,0xD70D6DDB8FBAFE8A,0x45BAED920DB6A932,0xC763B839E2BBE2BC,0x75D15837A8DD6A82,0x0742EDFBDCECE685,0x11C21981D312FBF8,0x52F7270B8120519B,0xC606843655DDCFB2,0xEE291DFA15C5440C,0xF721D53B8F27665F,0x84D044592B58C8AF,0xCC5AB956054A5785,0xC932879A6923A196,0x02D1D2E37D8E8D56,0x79694C2D7E6EF9A4,0x0663F9273D3C8AC3,0x1147C2A6C8300477,0x1619182B1831E333,0xD8548655EA3CD408,0xDC8892B0E8AB6F2C,0xB1E43A83A249F113,0x20FEB39FA89C05F5,0xAC89F594E0ED654F,0x2471D6E989EFC7FB,0x72D758DF9C908EE8,0x8F0150EEC6F397BC,0x4FAB71F13AFBCA74,0x09CEA6CDE6C0ED2C,0x84C6DD143D888182,0xD7A767D0F81AAA36,0x529C281BBCAC36B8,0x71F7A90758E7A76B,0x5A607E5961720F56,0x22A662BC36AD45A0,0xFDFD3EDDA0E3567B,0x857D7B2D7B13C048,0x174FBD980DC2EA62,0x4CABA3B25497C1E1,0x1DA5568A4F743D9C,0x47380CA0BC78DAE0,0xFC6D5C06E6350197,0x022F97B8CC516903,0xE5F04B09D1005FF5,0xFE5A3D72EEA9FE96,0x1E3ADAE3E04C1EB6,0x8EDED9E365297515,0x4B7AB32E32AD3361,0x08EA181C41A64A7D,0x6231CB04D04A4CCF,0x4E5D00136F415718,0x9BC21912451BF559,0x9921138880035DB1,0xEC0C2CED8D10E456,0xA6A2572936A9FB70,0xC0F186A2FBD0371D,0x81F4CA15C7F8E423,0xE380B45E4B2D6EDC,0xC929A602BF0D2F9B,0xAE90440FDD3766D6,0x8CF294FFE163B87A,0x11023B50F1527314,0x597A347FEAA5A60D,0x93B250CBEE6AFC54,0xF6662693AA8E5DE3,0x10980B7F51BFF1BE,0x3EA352DB95C6B9AC,0x6F106C63C087D22A,0x4C6A9ADD04D0F9B8,0xE8C4300162E3466E,0xDDE4A6BFD15ACD4D,0x1F6CFE6B4CC384A1,0xA630C71FA5247961,0xA9691D4316496D52,0xF142D254C387B04F,0xFBAA4D24584B2ACF,0x36EBBEDD7AED00B6,0x813CAAEE840599DF,0x73EAEF82AC0EDAA0,0xA73EFAA2EC718EDE,0x777D98B1E79B02DD,0xBA440D814232C010,0x843BCD208A17C04E,0x195F3F7026C60E11,0x3244BC6C091AB58F,0x68EFAFF034E4B717,0x17244366AC991EF4,0x55B865A514A3DC5F,0xA30959AFE758C82E,0x6A080A9E7E06ED9E,0xF5FDA71F2F9ACAFE,0x06C494B5E29E46E4,0x12CEA051410E95D9,0xCD10A8C173069B0A,0x9906B7F77F10A3C2,0x527169ECEB819DE6,0x4E327953D4285A57,0x803FF095B1607664,0x310C911D50DD08E1,0x5DCE1229EB33DF43,0xD21AB3846622DF73,0xB02FA210A20D7D38,0xE003BD2D70601C86,0x9EF578CB97E30452,0x3BE08F962461A2E9,0xB1E340740574F0A0,0x4D50A9E3FF37A036,0xA6F294ED6E29A2D4,0xFB46D2A1AAD1581F,0x230B83A9A863E811,0x6893A4BC3BECB23B,0x6CA92C881C162349,0x0E8B06D0EE858869,0x299A5EB011DFED23,0x4CA64AC684BE2ABE,0xB2816283FEA2E4B6,0xB956DEF17601678C,0x901D82DEB2534E71,0x31A9474DFA105FB2,0x0E318BD41B6C27B7,0x8E508972E02CDCB9,0xDE30F8573619F04B,0x06747FAC969B058F,0xC04A6BB9C1A35CED,0xC64D7EF95FD8FC88,0xE3074BC94ADEDDA0,0x38DEEF46CCD529A1,0x180BF011237CC3E5,0xB66E1AF255B42469,0xE7CC36A1CD6B59F1,0x10E2BF673EB7985D,0x8C7B3C8AB045DA6A,0xDE00C5C4C9DCDEEF,0x8C3577A0832D3A56,0xA8BA34E27E8278CC,0xD81C1A01B300162C,0xDF69680ABAA06981,0x80BA55BF1BA01F62,0x29D59173E1A330A9,0x37FFE8E9C3A67EA8,0x940574B7BEECAF82,0xA650AF6C0FBF05AE,0x86662C0C97D7C577,0x013CEFE53BD70D24,0xF032E8A90833FF89,0x90FF0F5606550070,0xE735195910AFA25A,0xD007927C04081AA5,0x07B1A54E8C7EDD6E,0x5642E6613553D7DC,0xB66194AF3DB200CE,0xA195244784045699,0x7C5BC0023CE35FDC,0xE9A912508A646486,0x2A6EB0E6EE96EE53,0xB65D4B6905BAD6C6,0xF5ADFB6BC4636097,0x44C46A6FEBF55FBD,0x4F32A1A73D453248,0x49905D7D86474AEE,0x6007BACECF063924,0x3B37177BD9273466,0x684C932DA52DA957,0xC868C0542E432947,0xEF6B8B5247BAD6E0,0x2C9963CADB77D311,0x19C89C7B40BBA524,0x529018941C11BB11,0x28B135BFB1F7C5CD,0x266F0598DDC10249,0x806609521BDF529C,0xD073C95A80928435,0xCC27C9E4E7E97312,0x3657C600AC628F38,0xA23731DD1B9D043D,0x1F948B93FB5B52A5,0x8C51E261C365312B,0x787E7401CCEA9886,0x49F5944AC5E6C418,0x1072A4312A9FFDAA,0x0B74E5A5DC49FD33,0x94A8D956231586B0,0xBDD0EF724CBA8A19,0xB551E5005F55EE29,0xC7AFB326B4A2CEA4,0x5DE7326443F1E640,0xA72EF7E6CBEF8D3F,0xC6D0B348685AEED0,0x5FFBADBFA87F0B67,0x72E312AE51323C77,0xBB9A026CD2CF1337,0xC3516921F64F3E34,0x549E76A86854E5FF,0x91AF89669B400DBB,0x56C7D152D70F4B75,0x3102F8A7AD32FCBF,0x6C03FC282DDC05A7,0x418E299F0FCFAD6A,0xD19C617D53F62A93,0x57E348C719C16012,0xEA6F66CE22F52FB7,0x4B949BD10F00AA2B,0xBEE592AA315F90E6,0x93D7AB39F8F5FBC7,0xDA2238A3FF74321B,0xE39CC1FD573B3CE1,0x2FFFAC0D44D14C35,0x546037DBCCEF88B3,0x54BCC3DA8D484A14,0xA4B02AA28A558912,0xBB2AB6794A5D2D2A,0x61656415FDD70013,0xF16DD8F1EC40D96F,0xA9B1A6A1D712668B,0xFCFE5FA6D2D97BEF,0x607404C171A28B5C,0x8313500122F236F6,0xB05B8008C1D9CC0B,0x93C4A46A3D6EE5C4,0x11FB00A96EE64109,0xFD9B38A605BF8387,0x21C91DC05C20DAF3,0x6D981FBB68DBDB8D,0x11C18F70ECBC0B5D,0x52C4A34E046C7CB2,0x8FD65D6AC4C208EF,0x8427522261953863,0x168A82C4BE78721C,0xD0C65D07901403EC,0x11C9F3C9E2580C5A,0x917BB461D18FCD9B,0xB6191D070CA54452,0xDE0E12C9551A73D7,0x54F3DE64D94DF85F,0x86AEAE26569B8371,0x5B9C13C02ECCDCF9,0xC1F5C713008AFAE6,0x67210217E4C1F913,0x7C8D7AC8E2AA2466,0x1170B4B9CA455DFE,0x35A04CA1CFA3A302,0x0430801F5BDFC655,0x9670FC4D9B2D5A3F,0x52FC9E2C4B6BAB8D,0x5B872E4682B8C267,0x6208B21AA457884E,0x5F351CD131B49E3F,0x42DA0607F4EF05F2,0x31CBEF0F4D72718F,0x1E8293B95A92CB06,0xCE3C104D4F7443A8,0x6E74FD042E3B13A4,0x4989EE74185C9D98,0x494405C05573EEA4,0xC789954A67575EC9,0x93649D649A4BE52C,0xD71580E901224669,0xCECB0C4C96FC4266,0xB78B926CDA416D5C,0x86E5E97C5172BFFD,0x0E952164E1AB3112,0xE0F79AB8B1C1A615,0x297FDA13D8DCA683,0x2C37AF9C6ACCD3F7,0xEFA098313B2AD5BC,0xB03EDF78ABB1AC14,0x6520ADC5A89BA043,0x582795C54B23F7BC,0xEA406A8AB1346AAE,0xD4EF8893064582A9,0x915F9369B8BD956B,0x585201C5D32BCE76,0x70338086AF34788C,0x2790E4ADBB3A950F,0x15B87FCC69CC834A,0xEAB746675D7A11BE,0xBD9874B1B060F086,0xE73A904D97FFB2B5,0xA1A708B4E5E96205,0xDE136BA81BA64841,0x99950CE60F1AD773,0xD5CAA9348BAB44C2,0x3DEE14E32559FD2C,0x45B8E72DC5C13398,0xF67B814DB76AF747,0x561753BA52F5957A,0x304298CCA73A0F9F,0x8B37D41ACEFDF7F5,0xE3DEF3C23B187EE2,0x00EE2305D4B3F6C8,0x109B33910128888E,0x9A5E22204BBA3D87,0x572457ED5913EC0E,0x3C57568768A2F4C9,0x3C3FB513A5EF0D64,0x37A220F574C07B57,0x06B5F4F68253A2AE,0x736593164D0FFB95,0x0861FDC3F5789944,0x988DA8F0AF30E44E,0xB4CEF5087D8A2902,0xD78FCE61E27C932F,0x9965074AD8671382,0xCB27FBE131214E2E,0xA9B4A6948A825BF1,0x34F056DA568B2C69,0x8BC62E380A360D7D,0xBA78E5FBB07DAF40,0xA5B2E68E675D9324,0x8B1A61F80B0EAB63,0xC3D987394CADEA36,0xB320A99CBAB82D30,0x0E0446C3C4972A70,0x8DC2286B4529E149,0xDF84EBB752024D50,0xA45B174204CFB88A,0xFD92C1561DD50F53,0x564D6982ACE98162,0x44F9DE654441B34C,0xC9B8BF558A8D683C,0x41E5C835C16FA809,0x8EE14F829CBEAB5B,0x0C20F79CF2A61424,0xC575E6DABEEC4B1B,0x3D6DC727C3A8FA8B,0x4F590B2A5AAFEDE5,0x329E6A2D8913A247,0xD01EBE5EED0A4DB9,0xC5D7EDE4EAEC434E,0xF18F48B59884F334,0x56588127E54B3F2E,0xDCD2ABC26DCF23B1,0x14D87DBC9621104E,0x59006F9CDAD98073,0xA2F0EDB93A488208,0xFD735182A7F799F2,0x5507373A6AE5188B,0xF68228B4EF39D3E2,0xDAE456B6B3C589B6,0xFDD065201EEB56C5,0x6263F6F0DBCCAA74,0x2D83CD3CA5216683,0xB2A2F4507928263F,0xE734CE438C4BB4C2,0x19AF051CC96B4C49,0xD25C832194A23DAD,0xD365177E103F4389,0xE7883E8582F4E67B,0xB12924004E0CB3B7,0xC65AE3615E1723D5,0xC38926BA1CD84C8E,0x18AF63B96513110A,0x1EB7A9890BE4E482,0xC042580695DBA761,0x609666F2BF23277B,0x85AE6751C84DF9AA,0xBD175888957FBB03,0x82D576DD4D081EA9,0x51A20F3C95805AC8,0x9413273352B5185B,0xB92D748E6A24E279,0xDC666AD58A9D8E7E,0xC3B249C186F759EC,0x30B60D1AC4ED1D28,0xB04C0A4DF9FC3AF6,0xA11A9CBCC4F9EDB2,0x7B76AEF3B37FCF20,0x380B62D2647A5B92,0xD292224D5CEBF8EE,0x907CEB59A34500A9,0xA9E935263FF7998A,0x03A40DC57308EAA3,0x1EA03F76E8C9F89A,0xB20BE004112C9249,0x42CF9D8753F3BCD6,0x65AFF5C3C1B36FE2,0xD15E67119C9A3F74,0xE5BC26F6D845D757,0xB505D92C69DCD951,0x009328B6636B7C06,0x70B946F500B5BBFA,0x92013F33D358989D,0x77F7CD9C567B1A4E,0x13AA23B4713D402E,0xADCBED3B61E1C7C1,0x7383047D7196F8D2,0x11B4C27F262A15DA,0x88382624FB069E0F,0xF3D0FA1913244133,0xE737FC6027F44BBD,0xAA3EBFC0A516B0FA,0xCB04F91463F1D223,0xD70E5A7B5377F606,0xBD4CF05F1637E5FF,0x9FB17F065BD89C51,0x4C382CA34010B55F,0x0D13B0EB05185613,0x48CB462D846CC16A,0x313A063D5B61611A,0xA940D1DDBA322846,0x91121613DD0B247C,0x959B84A3A5B2501D,0x4886E6ED3493C509,0xC6DF1AE913A30453,0xAE02A21F015CEDE5,0x308BA8E90294A3B5,0x6A1BBA8676D0A191,0x0B3EAA99DB29CABF,0xB233C3CEC38E6728,0x83DC8CD4537F8FE7,0x379AF215C65941A0,0xD441440211778466,0x01B2D8DD6FC30A33,0x7750BAE44558C24F,0xFE76B5E714948877,0xD4911DDC6DB44AEF,0xC70C769630BFFD2E,0xFA5EBCD0CAF53818,0x801D720DA42138D6,0xCF17CC7B47A2C063,0x3BBD7FDF85D682C3,0x45049CC2E7201440,0x45F55319CF6880FF,0xA0ADC19DBDA4C9C7,0x092F11CA76C44533,0x0DA7637C699EB849,0xFB5D019C4C16F04C,0xE5131F585FB06B3A,0x4C323D374BE6D747,0x6F20DB4104E1CA72,0xB035DC914E1FD496,0xAB81BC43FF1FC26C,0x71D154621E9FE1E0,0x5745E96FFF491D40,0x2EE6ACFBF3114D2A,0x63A33001A81D59AB,0x22FE87DAAB8AFAE5,0x93076401DE490AE8,0x318F1BA34CA3FFC4,0x2C035F735510C3CA,0x4BA6062E2AA6D973,0xEEDEFB044CA70A88,0x40C49EF9BC0252C5,0x935D134D0B345CE2,0x379CAD5CD4AFB926,0x490A4495FB2B17AB,0xF196C074D737577B,0x038073871DB351E4,0x3636382E41DCF41A,0x13D7B9C39B6C66CD,0x111EFB844A38B6EF,0x2ACA39AA7CF2671F,0xF1478D976F39FE0B,0x618BAE652D3F4B98,0xDED54490CCD3D7F3,0xDE38AFA84047F792,0xCC77D728E0AFE29B,0x51A78C80795B5E6F,0x4B56B1EF4CA0DDAF,0x1035404CF3447AB0,0x256E7B20448AB669,0x6A5E25A6F730B8E8,0x7A4EB4C1CBC174B2,0x1860C95322B0E47D,0x20039F49E0338D26,0x4407BBAB46B88284,0xBDA4C01CBB6BC444,0x591B393280325AC9,0x8CEC1FB500D399C8,0x7AFD4CE14137BBDA,0xDF8C0C069EB2277D,0x3E0FC67030CED327,0xCFD2C3B7A0C77FA1,0xF27DB4598279E7B2,0xB36F3354347EF33D,0x51C18A03947AF04B,0x8E55288D1990F9B5,0xEF32B139700B879F,0xCF6A881154C043C9,0x1DE9F7C12A737CED,0xB34928527AA662BA,0x4C0E38E142790012,0x3CB25A9AFA150397,0x6AA01AA9C71DE2BB,0x135429199EFEFC11,0x8F27C8D06E7D9253,0x1D3388C45E23A848,0x33EBF6E7EB85163B,0xDFE7266FD0ED8E95,0xC07973B411CD6F1B,0x46717BEF4A473D95,0xB6B4FFAC771EAAFD,0x20AA6C2126434A27,0xF6536C1E3FCC5178,0x8453DC6C036D05A7,0xEF169386D0982C19,0x42B6E7B025FAF45E,0x9CF8C615BB598C4D,0xBECAC7B7927C4F41,0x64E44480FE2130B8,0x6F8C16A4200C2448,0x4B67293FB12B3C7F,0xAAFCD019A2EA9670,0x61A86E2C89B184CF,0x11D9C08F6002C99E,0xCB629C43B6734F2E,0x653DCF86176E0EB4,0xB1DE615F384FA2F7,0xAD3928F32ACD6429,0xB8368D90BDA75A7B,0x2DCDA166EEC90124,0x9307C57A5EA3D722,0x24BFB9B0E967C366,0x3DD863C415ACD0DE,0x1B249C9EC1288E1E,0x112830AAE1BC63A1,0x67A56F79DF527528,0xE4DA073ED3132C4B,0x8A4CE20D537F7A4A,0xFD465903A41F870C,0x83A7247859366804,0x00D6B54821BB4E46,0xBB0BD4CCC66ACA91,0x5976113DCA44D906,0xE113F0938261F823,0x3C3E29D81973C570,0xF0E748E0672E5514,0xC19011F56D2C3FF5,0x73066E5FBAF57CBD,0xAE7C12C38DD19464,0x63579C5E256DA644,0x59539D2CDAE95282,0x6A68EC3D22E717BC,0xC0FD0C6960E4D1D9,0x3FD82474A534AC6F,0x1CDACE680AFCCB5F,0x8A722C793AA667EB,0x72DB35D615EADFDD,0xB8802959BD112E53,0xC20EEBC5C5A57D28,0x08C1EF9AE494A030,0xE0891862547A2E46,0x5A9D1B3B20A0939B,0x24F73F7F69FEA7F1,0xB489D92FAEFD029C,0x7E4E81A81E426E8C,0x360C43BEAACF5C4B,0xD5B3B615C0A10616,0x2C8EB4F04D291561,0x4BFE3F0043CB36C1,0xC9973225BC70715E,0x567390C28B0CCB14,0x3909A2A998EDC237,0xD5B75A1FA4002283,0xCD449815B112201B,0x2082EB94690C339C,0x59EB417355E2E5DA,0x0FCB4603B8C01EBE,0x0C91AB4885FF02F9,0xA06361B7F4DC9496,0xAB25BEA8F3AEB0DC,0xBEAE47DCF8C508A6,0x463304BE8EF1D445,0x715AC4FC045D45B2,0xBF07ADA3C95C21EF,0x0A9CC34ADA180E51,0xA132CAD154B47B9E,0xD726C3E5ED36F683,0x6EE85966F9C3B6CD,0x7DE49CBFA1FFE2E0,0x78FA62AC8B068183,0x35EAED518CF1BF9D,0x3C5C9D986C2B761F,0xBD0CE71BCAF170FD,0x9A1A8CB7D74E6988,0xBCEECB747C337991,0x4BC7A4A6220A04EA,0x758CB44281F264F3,0x0B0C1D0DF4363CF0,0x7C28002908E1C297,0xE642673ECCFF6564,0x167CE349BE244689,0xD68836D49DAFEE2F,0xB22A9FD7D8BE678E,0xF603482321980620,0x253981E2ED636B99,0x06C78FAA936ABE4A,0x66C58C3CBE464305,0x96C6423B83E5E156,0xF68247807A34DCF3,0x104D65F5812C0813,0x77F7712CD2837738,0x40657FF7BB25573B,0x88B2248D098E33BC,0x6AA772AAE82652E2,0x0DFA369C69FF189A,0x15399E3B0CD9ED12,0x36C0B8DC27E731F8,0x474169870F8A11F5,0xC5BD983A28A3F58A,0x6668498351413330,0xCA8D91F0598CC46E,0x8D885939B47AA042,0xA4CB0DBCC7205C36,0x35123CB733C43A5C,0x15E02D426BC21FD9,0xF365AD0CBF88DE82,0xB6032D051C389648,0xC38C6C3CD553AA19,0xD802274CEC6F2726,0xD9A43480E9DF5282,0x23391BE9A6C8B845,0x4055E20182AE5B06,0x4294187CDC9C09FE,0x0621B74790F26CD4,0x579F8CB6C7C50C76,0x1C6B2BAF8261C255,0xA5CB71E5DC022469,0xF695DF4D20FAEDBB,0xC514CA2697ABE7C3,0x236557CAD2494048,0xE957FBDD27C91159,0x705E00F1EC00FC85,0x24218AD6B719F52E,0xFFAE3AFD3BF206DA,0xD768BC2A793DCB35,0x0C1307B97B9BB762,0x7EE2215A5F7FEE76,0x0CEFCC9E4914EEBA,0xE042F901DAABB51A,0xB30F0136729691B9,0x60737F798DF1BA4E,0x1E3C5164C59849FF,0xDDC64D2EA984BAEE,0x4D392B85798CB014,0xB43ADEFAC909A025,0x5E0B4FCCFB64CB96,0x450D6C3156C21D28,0x82C2F1BAEB54CC4E,0x87A830859918A9FC,0xAF5778CD7E64A907,0x5FF08B044B23C69E,0x8E4B069DDB24197F,0x31EC6C5970D30C40,0x4E577141390559EB,0xA6C871892F8B95AE,0x7BB26C08347D88C2,0x36B30EC0D6CD463B,0x7DED674DF5B5BF5E,0xC9E6414B09018F1B,0xC994E267DC6FB98D,0x138A472204EE04C3,0x9FEA21726DB33661,0x909618AEB6D780C0,0x65B5B9866F7F28D6,0x6B53EBFD9B3A2913,0x7018AC22C62BAE9D,0x6BBA7F926D0B0D05,0x7B2DB632176D0B3D,0x368770F1C859A2E1,0x6A48300D8548ED6A,0x36D0DDD07F36AC0D,0x8F032B4C2EFB20F4,0x2F031C91F296C024,0x8A02077A6B5AA1F3,0xACF732152E65C039,0xE6C0E271B08FF2C4,0xA58D8901CC6D7A09,0x20A567ECDC7A24ED,0x2C1FFB470FE2EDF0,0xE14B90273BE720FD,0x0A3C28645552ED1E,0xA1B0360B2AB68B28,0xB1F35BA3F00DBBE9,0x8DC372D3E14ED338,0x3C6EDC8BE6FD3FEC,0xEFA723A0AF93025E,0xFDC882EDD62253BC,0xC5C71245D344DCDC,0xF463004F1C14EF52,0x670E438CF56FFC12,0x58BC9A6DC4C7AA82,0x5C323A4F75F9EAC7,0x39CFE2EE0AE9CE62,0x4AAC852EC2F7BC9C,0xE9911D1FB8272C8E,0xEAE6E289B4548C94,0x1669172FCDF72866,0xA428EA68E764C3A4,0x20351553866E9AFA,0xF132AEF88630B346,0xC93A076383935F07,0xB5445309834C7B61,0x29023CD72FC0F18F,0xD4750E79243652C1,0xDC302A906F287184,0x46D17557AED5F26A,0xD1AC2B7F9A718FCE,0xBA4B2446EF5798E6,0x6BA2AE03A18BB4B0,0xD8A216CD68FAA55B,0x321E42B378E8EF9C,0xB9C1059689E14C5F,0xB8F0ED8AC52509FF,0xB0A67EAF601A5C53,0xEE16786CDCCF29E0,0x8D70331877657A40,0xBE92E32F273586C0,0x8C27527943A9D87D,0x08873E0490A7DF83,0xFDEDF6AF090150B4,0x96F61325DD81CF6C,0x77435987DA1E13AE,0x84F1A9DF3F672258,0xDA3B84569DA757E5,0x39D9CF566E106890,0x934A398F09C41BFD,0x63CC2CC7D06897EF,0x184324E723826D76,0x4192A94D03C6D6A4,0xD31ABD7E2DB6312D,0xA883BE242C985C2F,0x96E6B54E948CF5EF,0x336EEA7A609C1B84,0x811A5DF3173913B0,0xB781DEB5FF20A1F0,0xA19E41469205D74E,0x92EA4D512184681D,0xF29E0AEC68AA57C1,0x99F6E910D6AEF8D7,0x28DE5853CF067CA4,0xBDCA7DD9F3BE69E7,0xB8CC2B7C89F73890,0x4DE3737198F4236D,0x70E8D8C4BC626916,0x401779F66EE5FBE9,0x87421CD8FE8814FE,0x3E37192372971B91,0xD4FC63CCAF56BC7A,0xEAC258C5E7AFC22D,0x3A528B33746D06EC,0x343D7519347AB31D,0x44F7B99A1EB84B27,0x23DF89A41AA5A713,0x483E6C182FEE73E9,0xF8AD0493826CE456,0x460C0F304A42C073,0x79BDC5E5878A71F1,0x26435DC5B43C7845,0x60947038BA9E0AF8,0x8564DAA09F3E4633,0x3A6B08EE7B875DD6,0x3FD222B57458B53F,0x5ED5A075A4A9A994,0x8D9DC23254DF1A72,0x12DF39BF4D17DD5E,0x4C5EB81963E34577,0xDFCEFD56C759CC82,0x4059DCD3006471A6,0x5741579DBCB9AED0,0xCB4F01C37024B1AA,0xA8C9D51773EFD457,0x2F043755525E3857,0x30422DD92B684812,0x21DA8D88070FAA10,0x7DAAFE60D3B8BC7A,0xFBBA00DE06E503AA,0xC0F52ED8E0016944,0xB105CFF15E48D0EA,0xAF425953007A3274,0xADB368CF3C6D1B7E,0xF63D5DC013DFE2D3,0x1B9D03D4F6621185,0xD75C41E56A339721,0xF8E06BCDF10F8771,0x0F092DD65EA7FF5E,0xDF4297540E83C75C,0xC30916D2CE9DA533,0xB9C15A4CEB25A72B,0x9A6193FAD5715876,0x2D06CB74EF6DFD7C,0xAB0F14AA861A01DC,0x8F303CD3C0EA09E6,0x677837A45D488845,0x180DF96753FB3EF2,0x4DD23079C149C532,0x152A931F406AC757,0xBE994B0B7F13B0A0,0x3C3E76867CA269BE,0xE2615C250D0D9E0B,0x433B396E8CEEA086,0x2753F4333695048B,0xA1B7DAA25775CFAA,0x39B6F19E92EBFB17,0xB9EDDBC89B1AFA8A,0x859508CD8D30AE26,0xB65E85F9018F76DE,0xC4CDC52A46AC5DF7,0xC1DBECAB32474F85,0x2038105B78328052,0xAB13705437F179FE,0xA4692A470D3B0047,0x58D05C1D9B1B445B,0x4739E46A058C69E6,0xCE16261D379D453A,0x27B6E8952ED34516,0x9B4205775CD4D76B,0x64A2EA473BDBF477,0x3C1A3D8817B1D15F,0x57A8ABB55BF06E87,0x3C057B33B90C892C,0xB7B8325F2D64A56B,0x57050865CCC92050,0x1D126A26C80BE064,0x64CD5054D361AA3C,0x6E5D1188DA7ABCB2,0xFD8F8B35CE7BCD7C,0xCB6BCB43E704BB5F,0x04927333DBCA5776,0xA5708EE62BE195ED,0x43EF00BC1138DE35,0x0FB40245CA5EE858,0x569D16E769175D75,0xCFBF32B0418B0BFD,0x0CE824BB8CF2963B,0x36F55D2233BC14C4,0xE6FD224928C686CD,0x40401A5B2ED0CFE5,0xEE675711092C41EE,0x682E1D943D9B744D,0x0E56B43487ADE9FA,0x3F4E8E1B23568766,0x936D361F10875C8B,0x20435846F9FD4114,0x1337FDD52DA83AF3,0x44C37EA0E889F086,0x8FC6AB46A8D7A1DE,0x7C1BDDFC96774A8B,0x65E6207FBD7669E4,0xD8096858C287E5F0,0x18E0370FBA987DC1,0x5F09F06B1F1F851A,0xA1668E0C5F4C6912,0x76D842A45FFF6549,0xF6892FAF38087639,0xCBE2BFD9A02DCF06,0xDFE1DC3C4CE82215,0x074D593443C7759B,0x1EDFFFA516D32A7E,0x7B3AFC06BDBEBE66,0xF29A80BE7360FE5D,0x63B61031191DB9FC,0xC9CBEB9557C9B7A5,0x035D742D40C30B19,0x7C1F480AA486195E,0xEB83F169AF76801E,0xE9F6D3681302DC3A,0x99A7A2627969A7F0,0x6B8E9F57B85748CE,0xF332DE878FA2331C,0xA953DAE5FFBEE168,0xBE2DF54488B5167E,0xD85282FE80D2733D,0xAA1BFC4496E202A8,0xACF667DA3DA6BF42,0x4E00856DC2BE897F,0x0654EFCECCBB005B,0x50E1BF4DDEBCAE5A,0xE4C369AA8E789659,0x117DC450EBB9FD9C,0xAC740FBAF2C28A03,0xB8AEE222C4038B6B,0xDFEDE36CE3CC4D31,0xBA283F0AA15B83D3,0x85A2364A44CB6247,0xED4DB66160A2E274,0xB52A6E0A05FEFBC4,0x0E3B12B39BA29D4B,0x81F639C1160C356F,0xB38A1056DA2835C0,0x55F932F8D50A1C31,0x2AD82F5819A7DF02,0x7893F1CC5877B5E0,0x588796D794469F65,0x84B1ED5DF4825AA4,0x3D07E4CFEC7FB32C,0x3AF5FB8B85793A89,0x86A620A1B0119BA6,0xE203363468D9DFCE,0x0937199975EAD8AF,0xF78CDADE0E1D251B,0xBCB06A836F586A92,0xD274410653FDCDB2,0x632F4B7175E3B3D1,0x3A625DBD0AB58E88,0x66BE5F19794177A4,0xC3877D24A4D094B4,0x8DB361CC2279C78D,0x5E5802696242A58D,0xC977229583A2A8B7,0xC4609FAD466E31D4,0xE12D6597C637BA93,0xC09EB1C7DDE194C9,0x2205DCA8B2EDEB43,0x7286466DC5BF1BBA,0x2EBDF9314AE223A7,0xD2170D8C6141A34D,0xC74321EF990F7EEE,0x35AB439690782946,0x4379E155275085E8,0x3D2DF9219AD99553,0x00F96C8F975D1FCB,0xCF34071792B48058,0x8D8DCDDF3C0CE420,0x7E7D12473B3C0665,0x4A6ACC6389CD2F16,0x2A7A84FA4E75436E,0x96F6DB589395A9F6,0xF5DE62345DDFCA48,0xB02542777BF3005B,0xDC9DC7B89B5A427D,0xE2E0D21D5E7FF669,0xF5F1B3555DC05531,0x2D6D51572F5E76C4,0xBA84D86A4DBBF104,0x832B804B62D8204F,0xDFCFE84B55267AD2,0x2E6B74BA987AF429,0xC8E0F5A14516B74D,0x37DE22F7C07B080B,0xD9C35ECE0ED0464B,0xDEB5CE58B1D52C07,0xDF6B6E8D60F91114,0xA5F9249CAB9C9B9C,0x1A8CB202FEF7A8FF,0xB5BE4AA8F18E4D98,0x2B6C846B3C5C79EF,0x6B0F663089302412,0x0A9023BB0B9AFFD2,0x1B26AC6A4FDEBF4A,0x8CEC59384102B2BB,0xECBEA65792DACEC6,0x5BF54A6E7AAF1C29,0xAEBFB12ABF70FE48,0xFA4109CF9EFEA923,0xBB31318EF6A407CD,0x75973BA05BFD89D6,0x1FA9DD18B624D382,0xD5369AEB37BCC534,0x621B37A822273AC0,0xFFD70FE57F3D9B89,0xFD1C013E919EB17F,0xE6CF179E5AE16CC5,0x38D62C6B4D156FF4,0x014D44143EE3CF0A,0x94A675563B51DFD1,0x9EFAD293B455B615,0xD07833AF6ECC2186,0xE34838EB10D98407,0x25C93B38753CAEBE,0xA07A8B5FBA5907AA,0x973E9C5A3CF08BEA,0xC3282621C80420F2,0xB511CBADD993159B,0x2BB76C00FCB52209,0xC8EA42CE0FA2326E,0xE5F23EA40F63D06E,0xD653BCA80CB376F9,0xF3349D9D9069DEE9,0x3CCA2C128E3EABE8,0x2394CA7B970EA0DD,0xE17F38E2B6D4339C,0xDC66DFCE02A9F751,0x44F95BC0091EA542,0x80D027009BDCFCB9,0x8886145E6628EF34,0xFDCEB293B39DCD00,0x5D92F167A9895AA8,0x53CB6C5A101C8D9F,0x75FB4D6A138AC2F6,0x00616018CA20E7D2,0x680046EBCE18BF67,0x5C9D3D5A0ACB058B,0x5547A8070A7E0931,0x9C1604251BF4AEE9,0xE6064A340C7FD7E4,0x5983EC2BF449CA7F,0x0CBCFD0064D4B74E,0x90A32250CA2EE2C4,0x4A393E9533AE5312,0x5FD235AE8667171C,0xE398DC0E8B21B230,0x7DCA3E0142BB3B1A,0x5E3B4522969FD9D7,0xF0EB748C1E3A97A3,0x88593FBCD1605349,0x8434CAF34DACFAF1,0x985B7DD4EA841828,0xF84694EC9A4E4333,0xDE6D654200DD60F9,0x2DACAD053B15FF1D,0x8E2F59D052A661A1,0x24FC0BB43685433F,0xB84D613830E5B87B,0x656B068C839FD5FD,0xF365109953B3F925,0x940D19052309E289,0xDE323EC29F82CD04,0xFFD2E099796F579E,0x5AB8FC4B26EDE87E,0x4503580B8738BF6B,0x369FE79C12713AEF,0x6CA82826A9E12A6E,0x4752D491237AD773,0x7B145287551258DF,0x5D5CD8BCB1E66AB3,0x9BBDC1E2B540ECB9,0x61134575F336623A,0xF5C34C1C563F9057,0x7D482B5E26297386,0xBB57AF32090BF2F6,0xF7A3EC4593408C18,0x342C2DBF57847BA3,0x0BEC1591DE963482,0xB5D1891586DA3479,0xC14ACD2C7112D6BF,0x7DAD4D57D1EBC7ED,0xF8096BD625D0699D,0xBD91810385E55628,0xBE574DA53B4771FF,0x7639B3199AD49573,0x777142A22E32A474,0x407AB2121ED742D5,0xC5191CB22DBE54BF,0x3EC8AE9AFF0348BF,0x67BAEBA6CF87CDAC,0xD30B612D9CEEB0A8,0x79BF3DFAD8900576,0xE2B7E70CC146107D,0x7EA0CFC7EB44E1A4,0xCB4DD8EB1567CF45,0x4CDAA4E4E656E6A9,0x37A0904F0CFF52B5,0x0508A608BD1A698A,0xDF00DAF9A4F61580,0x5AD04124C91D893D,0xBF61EB806DD3E413,0x495967E712A94B05,0x09BD35D7F3D85169,0x9C0F9F4A20EC3C33,0x603943B82F67DB7E,0x99B60DA1F35A1BFF,0xA66736723E026931,0x03235816F0614205,0xEE3D75B8F903DE2C,0xD75BD8B1682D58CB,0x9082EE68FB50737E,0xC1813B7939F9597D,0x64F0561268D64848,0x2147BAD16D369C7C,0x8BA11C27A9131470,0xE980BEA2681FEA3F,0x7908769104774C75,0xCED8103F69A25596,0x83A715C46DA09EFE,0x4D5CAB91C1EC8BCD,0x825BC68C22898E39,0xA95A57B3FCD84F54,0x8C7F9F03DD2D18F8,0x6ED59CDA9A3732B4,0x167088A182B32974,0xC5E509F060206C92,0xF0CB5CCD6379BBA8,0xEF43445BA0AD44CF,0xCF0D33EA1ADF7FDA,0x4A0C5114D45DF8C6,0xBF0E0547BB953705,0x9D5D4881A963CCF8,0xF3AF6F6120A2256F,0xE7D245AACE794FB5,0xBA2BEF155ECBAE3B,0xB9AF7DFF682165A1,0x1C8296F71CE5356C,0x1640805BC7A569B2,0xFBC106A6291BD4A8,0x75770E3E8E6D230C,0xEA349C7BC0E3E288,0x8D8EAA9EA6825CC7,0x4CA1B2E620262156,0x74BAFD9257DBD18F,0xCDE74AE809AA6AAC,0x7644A936D9FBF47E,0x0E467918749E2D26,0xD0E881F4AFFCD728,0xBC7CB587A5172341,0x1A64630F99AF81EB,0xDBA1D4B01154E78D,0x316A4C6D1D5E07EE,0xE0E35AB7EF0CC4D4,0xCB26C4880CF3387E,0xBC9E74071A838259,0x56F54BE468668FEE,0x521908E771EBC9BD,0xECB3F901DA8DF2B9,0xA307CD44EF771B4A,0x88E6F6DC2C94E317,0x39360DC75CE2DA99,0x732C3A6B66734DBA,0x110DB269ADE267FE,0xF705EE04BC702365,0x5F63BFB7B789607F,0x346A3F1DAB0E1D91,0x637581086CA1F820,0x1F3E832E2B6E8F10,0xE20023C4B27BBA97,0x76C37C0206AE3671,0x58D4C497DAB4B80F,0x474E0D1806CAB15D,0x68B30B6B23878DC1,0x45E16E50B5659A28,0xF2B581A61EC558F0,0x7BA30523FFB294F9,0x6BBB22BFFC0E23AC,0x2563E0D098139E08,0x23C7C92FF57756F9,0x56500AB9FB798C8C,0x9F38870832C5DDBC,0xA4245DE31F9A1A90,0xD820350C0843052E,0xDEA15D4F3A8B497E,0x6C9A2E2D524FF20A,0xC222AC87F41691E3,0xF8054FB7B0627E3C,0x6065FEE4EE5D1F98,0xF03A672E614E615D,0x13750A34D9A93972,0x516A794CBCF03163,0x98972663D07C732C,0x782C5211423BF01F,0x0B6CD8EB0C7919B7,0xC41025F9D81603E5,0x458843F6BA1FA390,0x4CB6653D278AC1CE,0x30F93745FB4F00DD,0x1D77F5BED243C5D8,0x9B51221CF776A6BE,0x93FE659A91D4705D,0xEC7716E3F1510EAD,0x77019F14E081D421,0x812A8CFA76E6EC6C,0xA5D61CDCAB6C8715,0x6E63E96CFBF467F8,0x4DEB97BC0D75ECC3,0xC62897F4183044DD,0xDA75A57F5E6263B7,0xE5EA172AE22DE1C5,0x2DFA95CB24E6BE9C,0x26D2462D875868C0,0x6972CCCFCCDE7E91,0x38DAFFD3B47CD76C,0x894814DE4D3F1797,0xABA8258278F9C5B5,0x1B7C9DF3CBF455F8,0x5E87D8658ED3FD44,0x80724463FBDE02E9,0x2C7E4E10FE407710,0x920E0198F3FE6F8A,0xBD98A7E0AA7C37BC,0x7FB895596C1D6CC2,0xB23E96072AFE0A2E,0x90786DF671DE5673,0xAF7B698D270CC366,0x6AA8A3CC4FDD5279,0x4A06C4339AB3410D,0x15AE13F205A20992,0xE5F2A33DD87E4B1B,0xC55676C523AA2A74,0x12BC7962E9263ECF,0x3A872F5CAA994DAD,0x71624F36E4F10A69,0x8348774E1E7072B0,0x5B6B63918CB6C1F7,0xF206F28A414B63BD,0x09CC450635D14314,0xFEAC4FD495D95259,0x7396ED04E57F35DE,0xB3BECF8901AB17F5,0x5F22B8B3908E5BFB,0x57445187011029C9,0x53CCBA426394BD16,0x2AFEC1C6CFCE12D4,0x2ACE940538ADB7F5,0xC5B16B2218DB7C5F,0x5C58B35B13CBBAAA,0xB536E332B65DF6D2,0xD7EF42C713A32979,0xB31AAFCBFAFAC20E,0xEEC2332714788988,0x1559E4FAE7A0F9F1,0xE008920EE02A68EE,0xD6544A9D87FA31D2,0x9BCD8EDA673D53A7,0xBD17E9985520BBA4,0x50080AA7BB15CD8F,0x17AB9E16183F3D60,0xC0BD869AD76549F9,0x92FEC1CB1128C52D,0xAF70B9CCAC333215,0xB3E40857903FA9FE,0x7A61396BC1706831,0x250902DB75F15E9A,0xE7F797030674CA0F,0x458FBAC2519B47D9,0xD74CBEDD86EAE71B,0x5E72EB2DC63ACB95,0xE3F9A9E584CBF6E1,0x674CA1B13785332B,0xFC46AAFF5811566F,0x4642225AC5388A3F,0x429BCCD4D9CD519E,0x4F04CC8C01D4A58A,0xE9AF51CD1E535822,0x70F3392FFFCB2D68,0x12DA0B0261410C08,0xC33CE558B359D6B8,0x46166BA248B6D3F7,0xC556AC91ADC8522C,0x3142471FCF8BC1F1,0x0C8071BDE3ADAAA8,0x281F2405EF3B3A8E,0x0C9375009667F7FE,0x87FB76FB82E57343,0x03433A8D9D9171BC,0xDC5954254EA24055,0x51271BE1F494C606,0xCBB0D2B8D9C0C16A,0xDC1FE1D8D726B15B,0x43E6C2625A567913,0xCA47326EDD3AD2C3,0x82785E24AE98C5D0,0x194697CE13549C43,0x14AC4B89FAA42B19,0x2C78D8C0561E58CE,0x65613D430AF190EC,0xE02C18D5EE030096,0xC2701EB146A77430,0xA00796AA9764E69D,0x036547CCD681C496,0x2FD6F46DFA437901,0x9CAE2CF125561A2D,0x60CA5B6A8E05ED38,0xCF04AA4CCC3135D8,0xBC769000F754A7D7,0x7C7E8619A5599EBF,0x711FAC52B6390867,0x1D314A9433882DE2,0x0E6B01F4A365039F,0xC979DBB1456DE6CB,0x837E4895FEC83EBC,0xB0908D3B9DFC02E9,0xEF9681E1A646730E,0x13B1FDA1FAF08EEE,0xEFDD90E4C1C88039,0x5CF872D68B950DB9,0x88F2103761DE03C6,0xD3BA3CEBF00B65D8,0x6E3C974E2D2AF0F7,0x7B1A2E33476E2206,0x74D2DD95F772BC5D,0x9CA75ADC82A0379F,0xB774696032038AC5,0x46E2CF557E7D8EB6,0x283BEBA250CAA1CA,0xB8D2CAE55B9BB8A1,0x3FBB311AB8555625,0x0AA7BB4B22A7FB75,0x0556323B59FFFF5C,0x4A3AEDCB23C43BB2,0x84F9552C9AA4948E,0x3BFB36CC46F42AB2,0x860030E3721FB4DF,0x09602C44A1B36213,0xE7CADCA88972D02B,0xA413B3000C547565,0x5B49D9D8DF853995,0xDB71A50F5A94E375,0x49C70D37F123353D,0xDFCC72B2D70FF5A0,0x3F82CD669E548E88,0xFA6867DD2D56B78A,0x566AD3273E9E684B,0x56A635BFABD9A85D,0x9A2CFFF4FAEFB194,0x0758F4EEAADE008E,0x2D9BB472B33D0436,0xED63F016CCB3C59D,0xE812EDE1B294002D,0xFD506FA3C5444DCB,0xE4E1745BF466FB25,0x3DA971A78AAF4807,0x3FD4503019FCF269,0xB933159F1EA5FBED,0x031A87D59531F47E,0xB25F8887D898AABF,0xDA0A07ABEDD94310,0x445C7A7E371006E9,0x0D1947FA0456060F,0x6C9372973C8BF2C4,0x09E2E26199012E05,0x9007BC74B7358B92,0x7D391711113EEBFB,0xB01B90E9D02FB6CA,0x85660A6516A662B5,0x69F7ED825CA61A55,0x29144CF4D98DBB45,0x1912DEFB2CAF1352,0x356C521A09C1952B,0x1D2464FE4E0E5F38,0x3A73E3CD2AFF1D5F,0xA7CB66863E0BA448,0xE9774A4E26539710,0xF26231239CDAE014,0xD4CEF2F423BA9DB6,0x2678EFE728B54BAE,0x29B395C2F0F15964,0xE5042DAF4D6857A7,0xE50FA6B298DBF65A,0xB6E15D2EC7BA39FF,0xBBFF4D8F55457B45,0x116696C6A42B2E65,0xA204E7EE4B3FA8D7,0xB0BE743E7F6C5BFA,0xBD391BB3CEF16551,0xBDDEE4E861E572CF,0x9EE9A1CCA798D4E1,0x0E06AE6204DB0AC2,0xA7EBF91DB69FF2D8,0xB5E96DA56F7F6AB7,0xAAEDCB645754DE97,0x3544315B1287E3C7,0x9A42F04600502E53,0x3213E49A4F299E7F,0x9206A29281F34E84,0x3F5D3DEDF9986198,0x99704F8515AA4596,0xCEBDB01BD82FC5FE,0x3FAD24F933B7DBFF,0xEEDB85E8BA416BD6,0xA6FCD2146E9D06A6,0xABFC97053AB3B504,0x695751D6F55D837C,0xF13890181430C164,0x2C78733F602B837A,0x9F0800BD89984231,0xE16AD7408AADDAFC,0x99F0F88AF59B9647,0x70A78E836436BAD1,0xAFDEA12124E6B1D4,0x06446E631749C194,0x9628E2C08A55ED43,0x86225C5D8995B99A,0xB82F9985F6858EE5,0x2ED25BD31D371F33,0xB216F0C1B3169065,0xC63F2978830E51B6,0x6A6FE150E1B596BF,0x6B45762EF75DF075,0x0740D7369C8C085B,0xDB0803EB74F01CF8,0x1419B8A28046E24C,0x62AAF0140FFB68B1,0xA006C789D6AB3ABE,0x432FBF29B2564EF1,0x1D46148019066835,0xDDB7B97FE3AC791D,0xB59C9E6587E425E4,0xD1705C550F7CC1D9,0x9164E57E3B4D5AAD,0x5381D4B6CF851BD8,0xD6747072ABF00C09,0xC671FB43301F7815,0x584053DB026FF7D1,0x46FFD7A7F7E70026,0x2E26C27ED42B0339,0xE54D0936D86A3663,0x744FE0DE29C00C20,0xB9290D386F9AA678,0x0304C9AA3EF56077,0x048B42D6419DA5A3,0x67B3DEF3D8152167,0x0CB39083A37A75AF,0xCE95283F3586031D,0x435DF884BA45E83F,0x530867151E3339C8,0x5D2FE8F9BC159EE0,0x43DD28ABC20D5E6F,0x6773098FD32A2309,0xE0678D660774C574,0x58578ED83DE2643F,0x3A1146B6313A4F7E,0xD4D35CA5197C1AB9,0xCA9BA2FB5C506447,0x4EEEC448CDD760FE,0xF02A47317F38AB4F,0x757325DC25AEB4E6,0x62FB54D47B1CF10B,0xCF0F0B365831BAA3,0x6EAC46597BDF9967,0xB63074672C4C4691,0x137213577063C7FE,0xB2A0C62280AB9431,0x1DBF59AFFD05B27F,0x847035E069DDB56A,0xD1BCEF9A7355BDDC,0x3F6D8B38423A4342,0x91BFE3448A53DDFE,0xA9262B2CA306ACD6,0x7DDC7E0882497988,0xD6AECE3452D48799,0xE6C2E658AF1EDC4F,0x927185DA828FF959,0x4A941CD07058DB48,0x141460B3870E8292,0x7DCD1844AC31EE2E,0x5230BCE8541148E5,0xC15BA3D40E933E62,0x785E779728EBE6B3,0x4C2B3FF5E452349E,0x386012D8A2314217,0x7EE77A0BF682619A,0x31D885ACDAEA9CC9,0x2B434265F584CB70,0xB19DCE6C953262A6,0x5258864923838838,0x7558AE1B9FD43F5F,0x1FD4114ED9EBEA1C,0xE78CBD36140D5A63,0x613EF4E498E50561,0x363696F10131F903,0xECD30731420DD311,0x78C97642080AA532,0x818AF2AD399BC67D,0xC4FCAC49633C04AD,0x55DA07110E4F7096,0x1257960BF2E21246,0xD3932CBB803EB3FA,0xF2A2EE01F11E9623,0x0A4141E45F2A5089,0x2285DCF88131574E,0xEAFF900EB07E7853,0xB3E3CF9298AAF8E4,0x4B66D07FC2B55321,0x12FF43165D1A16DE,0xE7B34B83473D59FE,0xCA6FD77F66FAAD62,0xC1A69130ABDA551A,0x05D1F9A29A0E94CB,0x4CE8E6A1495F7B63,0x726E0E93A851F459,0x6AD7B5A539CA9354,0xF4A9514F67F2269C,0x9A28B3F927708077,0x44BB4B20753849D1,0x8D8628D2213557A9,0xBB5D269F55A39B78,0xC740EB92BEBD53C3,0x29E4218F7B615C0D,0x66D207F7DF9E9A0E,0xF841A0886BFCB714,0xE437AC064AFF96EA,0x42127E1F167FBC84,0x4BE1457C30756C12,0xDDBF3B3B8C97D438,0x11BE28448FF78EC4,0xBFE77DD6CD13280A,0xCA256A1F38FE8877,0x0C1E0FAE62DE6697,0xC84339288EF70B28,0xC0561E75F5EDEB21,0xB424AA7200B03F49,0xFD02E7E97C7C6E15,0x9BBEBC8C1CFD0CBA,0xB47E928A13B33BF0,0xF790BA162BAB7E6F,0xAA14633464F7EDD2,0xA71EE7BDD6A845F3,0x980B1A4DBAEB788C,0x976547BD7D6F38C8,0x2E9C62EB714F3F4D,0x682B95A482867B21,0xC5E9F6DE8F8EE218,0xCA2E750A4F115618,0x4B29BA37067CE68B,0x4C25436065A1F74A,0x40D7F88F7B85CCD9,0x6F7507EFC12666FB,0xD0E907EB4C483FF9,0x4023B90F10A7EDD8,0x4A34368BDF4C8905,0x1C9861FD763595E1,0x3932B20CB533C2DF,0xEEF3E5B4C8D798D2,0x15CDFDBB5E09A352,0xF88FF85D4B1D64D5,0xEC27BF8C74F23ECD,0x3379359998E3474A,0x57C37DA0B76FAFED,0x28D25C2C95B12CF1,0xA220438E9B96000A,0x9956DDFF654FAB9B,0xDEEAE6C412EBF8D4,0x56087BF30563C311,0x3EE3C4C45CDEF6BF,0x0C5FFFCAC4F695A7,0x296CA68E23B30EDD,0xFBE35280C7911077,0xA35769DFC07816F2,0x88866FC0390226BA,0x369577167903D019,0x92BD4A219B293F8B,0x6F40788795EE91E4,0xAF9024E1C3F66D22,0xDF53D4AADFB25780,0x03652C621F5DA5DF,0x4F19276AFAC60899,0x60A6E4E30C30CFD6,0x3D8A3FAF73C78CFB,0xDE9D244F36FF99A7,0xD03DD34C9E2089FF,0x8CB5BD23ADAA0ADD,0x0CC6389FEE49305C,0xFDB573FC517E33C6,0xA4461EE60AB46BAC,0x074D6041187BA994,0x329CA957CA6822B8,0x55471F66A00C8DAA,0x277005A428D71E0B,0x92FF2500F8C898AF,0x6BB05950ED7C4CF5,0xEE1084241071A2AF,0x88296BF40138B852,0x3AE6FE1B7F0723D3,0xD95561BBA1297B83,0x2D1281D02A15932A,0x456596E06FE28491,0x48E2504DCFB89280,0x75CB81196B1AD162,0x8A0FCFEC1498BF6F,0xBA21CF6F43989709,0x3DD8F7C80B9F484C,0x50499341602A966A,0xD9B3FD1DB39720A0,0xA4414550843FBF5C,0x192ECBFB66679E92,0xFD80791565B1F5F1,0x95A359520D0941B0,0xB6D15360A5CD9FF8,0x4874FDDC58A29878,0x352FD0845C85C7E1,0x67F44D527EA2FAD5,0xB0F352A1996CD38A,0xCDCD85DBBE794D6D,0xF7E789D5AB747D50,0xE339F974D8B8ECA7,0xF33D96DC60471CB3,0x7FB0CC2DA5D588EA,0x99539DBA1AEFEA4B,0x373C49B78D4B5B6C,0x33D594C2338475E6,0x8418CA18B8894D29,0x75D04EE8B3E4BEC5,0xD8F4080213A85450,0x2C73B79FACA38ED8,0x42B1AF928A212537,0x03170B9CA8A140F3,0x9CC0F6FCBFEF8EDD,0x9EA1E255CAD58EA9,0x27C9337759CDB787,0xF7968811944D3AC8,0xE87BCB2DBA6A9929,0x9018965838C6856E,0x06558A78C1AD4F45,0x83DCC4660373B5FC,0xEF7FB2FE57EF3493,0xC36287CC903AF1B0,0x5C4AD877DCCADFEA,0xA40BD81C02BF2C97,0x177A860124D20B6B,0x45069B05824670B9,0x407B37EB438A72D6,0x0F1B563523D57004,0xF76B86D8D2C7DA14,0x3E4637DE9ADE8AC2,0x94F905072E3A9A37,0xF2619D2D10BAB4D7,0x48CACE87AB333097,0x5E66BCF605CCACDE,0x7661E72A0B3F856D,0x74145FF3BDF92F78,0x6060AE419989CDBD,0xFCC57009E5BF7606,0x015938E674D55E84,0x4AA4B26BD8F453D8,0x20CA81A93049AC30,0x98E41C393977FD5C,0x56C1BD4158D9C886,0xAA4F1BAFCD46D087,0xA51820F79EAD9197,0x5137436F8A60C657,0x58FCEAE943DD62F7,0x6D313132C7291C00,0xC303CC93F8B1BCEE,0x0B2D23181345A76D,0x5B4FCB4BE1077655,0xD76CD72303B6F4CB,0x29C89DCAC5B04747,0x2A337C8D60D247D1,0xEC8EE0FF61F74192,0x5179F504EE89D9AF,0x2BAE455AE0B75BFF,0x3DDF0BC05CE8083C,0xDDDC06F17DFF37A7,0x5587F48A4EBB9750,0x649E576C4C5FF374,0x0D823E63AEF7D67F,0x1868B3998874B354,0xD65BB01B05A16A65,0xC8F323A7EA04CDA7,0x1B0F8CCF9E00FC5C,0xEE1CFB21F03A078F,0x2791F001476DC476,0x01B0133FD34027F3,0x3217951F877D8717,0x0FCF3B6D0D310247,0xCEA33D9F5BEC0877,0x46D34A547368D5E3,0xA8579DC444ACDB9F,0xA47D7AF2774AF99C,0xF7867CBBD35B9229,0x20B3A531EA8BDF13,0xB1BE4A69270CFA01,0x73BFC1738A3B25CD,0x04D58F840FC39D72,0xBA849F13026C5FE0,0x30E7958D33BC30CF,0xB596F8EEAAE8EBA2,0xB779D103CE4CB23F,0x1F13A8842A2A04DF,0xCE0F12CA48B5FEE4,0xDB35251DE7C2235A,0x8E1F354953FFDEDC,0x20DC08F0150C896A,0xB89EBF14F2911306,0x99045EDA964DC6C3,0x42EB4B341D4CDD77,0x71C7E73C895B22E8,0x9AE2CD8C5E439968,0x443DA6675229FF32,0xB79DB35F796D3024,0x6D19828B1E4FAEA1,0x9EE5E8F26A7B94A3,0x9495DCB1564AF86B,0xCBD7261EC3F459EC,0xCE31F04FF29CC64C,0xDAAE0F7DA7BD6132,0x817A9F8E1E3BC9D8,0xC6F0240A27B1A6E3,0xE53C1B0ECB799733,0xCCE63D8EE029D997,0x776E3CB9CCB19C04,0x77A558AB62E9B70B,0x959DCACCCB14986B,0x2F6AAC3455808A55,0x6C2FC7CDCAEEE861,0x493E5871BA5328D4,0x36D5C5503F8E9884,0xCC416F91E4C9ABDA,0x741F89DBE848F033,0xE700270FCE09F40C,0x5D00DE74951D16D3,0x4CE01205EE435B2F,0xA969A8A6D24840B6,0x2AEFFDC2E34C7616,0xC2BE9DA0FDF29A9B,0x94EF863D4C5647E3,0x630AE8495DD95169,0xB9E17C53BA8D0414,0x0340C70ADCA01ABE,0x92A9EF900FA4F53C,0xBB21944A549B58C2,0x46497A1980E43DC6,0xC463D03EE1435B13,0x9286B637235FF247,0x725FEFEDE61D4AA5,0x4D1D34A64ED210F4,0x523528AA45194C2F,0xAE1F0100CA2256F8,0x6A1447122636D1F3,0xDD88E679D77B214E,0x878BB9B9DE1E3193,0xB9F3F55C9C1252CE,0x22AAE3B1313EA349,0x75DD9DC3131E1DFF,0xE64402F3812CBF1B,0x102711405E7F7AD9,0xCFAB3E1C032C2A67,0x4DC2D777004D8B84,0x6A74E2DF1D000FAE,0x2B5F80DE7726830C,0x6ABA1A35873649C2,0xAE7D2366F7CECFF5,0xE184E490B4C08DE2,0x280215946B8D4747,0xE29A485785F28D19,0x16DE22F711E30A3E,0xA2DEF47A35A02F14,0x37BF1E3A031F8C16,0x150C997C5248D50B,0xF845FC41F519BD02,0xE36D8356BEB05B7D,0x6ABB2CCBC2AD15C5,0x36D2E5ED63FE91CD,0xF85C6AD2823DD245,0x9FC7A5E40B6DDC82,0x28AEE87388DED69C,0x9D112A5A6C230761,0x4A9886C9D5F76CCA,0xD0F511D37F4A110A,0x4C80F9E3A2078ED5,0x6724CA4AD42E02BC,0x87829D7E7CF469F5,0x52C466D85B0BF292,0x00156EE9BC6B7453,0x879CA8C10F30EEAF,0xA619463161959CE6,0x9F5AE5748A025816,0x135F2B194486E167,0xD959685F0E3349CE,0x90041CA44B4847D4,0x58304EF57393628A,0xD17AD8B93E6783DD,0x6EE7AB5E30764AE8,0x37592D05EC91AF40,0x3C02571FFB044FAA,0x7EC1B9FB142A2A28,0x767275C6AEA9D9FD,0x31569D2E1720ACAD,0xBD72C8CC5C173760,0x740B4D80803B4472,0xA602F576B084E1DD,0x22F5C780F020B87F,0xDD518178138DBF31,0xD58AE8C6CA51AB40,0xB67541F5A23CE801,0x794E2D2EFE2146DA,0x8A0ECF24D5FA8AD3,0xED2FFA46DE62AAE3,0x634D7CA770FD3305,0xF3E99A05779E9B0D,0x8C96FB4718692F08,0xD17DB15B98EFD597,0x96E492BA5CA3B23A,0x8CAD7E61772FEF52,0x0E0B3CCFAA345B2C,0xD457B61C9C578B58,0xC2F304B5D0F6EDD7,0x00C9E65B39A4F77C,0xFB8DF3609F27A4A9,0xF1B73DAAB9F680C2,0x4D495391582576FD,0x37CF0F6E75C4D354,0xD9A1B2512249AF8D,0x08EBE13C550E12A2,0x960410E2227BDBE4,0x19D6C7454C0FF433,0x2BD0BC909EA0C04A,0x9C8076AD2CB55026,0x2C60B08E44D125CE,0x95C7C9C15C72A95F,0xF38B7D01C2BFED23,0xA434A70863ABC6C3,0xEBCEA25FFE973F4C,0xB5EA6AC7B274812C,0x405D9B1BAAEBB1F2,0x0FBD7D2F180DC1B0,0x66ADD623A1455986,0xC2796E6CC8E1C996,0x3A81CF83666CF4E9,0x51DCDAC420343B04,0xF7BE645B919CDFE7,0x9E9069F8D62B7480,0xD53C0957A53A2028,0x31C02F7C846BA9C5,0x91571DDC512A549E,0x5F66DAE19754FA19,0xD468F30E956194DA,0x6705690A21AC12E8,0x884B1D30129E7DB3,0xD3805812B35D8562,0x5C35D7B251BAE7A4,0xA02D4E3D8E7210E5,0xC78CDA2CE827ABB0,0xD45EA57ABCBA5492,0x74304BDCDA751D49,0x344D15511FF39000,0x65590CFE7FA0F68E,0x8BD685CDE2B23448,0x90678E3FF5F0D196,0xDAE4E91FF8943023,0xCD863473506DEFC2,0x48E3208D73A0D207,0x8077EBC357F1B8A8,0xBFF6F2B83B5BE289,0x708AE39F0AA94FB1,0x6F0E8EA674B937BF,0xBB7C5E5B5E6A3C07,0xC62176678B43C270,0x0FD3967792D750AA,0x6DBC8D188F155ED6,0x9A4FA76FA8DF8B26,0x46249C233195689E,0x340EF8185E2E5021,0xFD80073AB2C3F683,0x13DCD7FA330C350E,0x4C011867252BD093,0xE3745D01F249B5AE,0xDF9241CBB877703D,0x7E6233BB86FC58CB,0xC15752DF29F5F41E,0x4BFB46A8458D6FBA,0xB7D3D04C8881DDA9,0x667AD9FF3B8B3D6C,0x070FA5792CDC98B0,0xAFB7B8407498DFE1,0xA38AAEE8698F5AD3,0xA84865E65AB4AAFC,0x5BC7CD5F13044F7E,0xD786786CEC0451AA,0xAAD902C7D7A11A30,0x2931EAF442F04C9C,0xFE1DD6791787AE36,0x1856A79AC7DE3A4B,0x7A434E45CC287A1A,0x01BABAE7101325D7,0xA5425C2587DF3B5D,0x5DA1D2C5A8147F46,0x3BC1E9D231996CAB,0xA6AE0028CFF8A354,0xA1642340F2FAC102,0x69DFD4A53A209820,0xF8BC46C711EC81CF,0xA1299ACCCA0CE4FD,0x0E950D58E05B7C53,0xB80D7327B5C5B415,0x374DD0B80B0BC142,0x4F1D110A7AD66021,0x5E0822F9A2E032CA,0x35BCE300213A8818,0x822C82A4486140A1,0x301BC6F76D316333,0xC485347BB4359385,0x2CFA4C285CE3722A,0x78DE622A489118E2,0x76F5ED58F149BD22,0x8E8D43AE103770F9,0x81A94C5D610E47CB,0x5702320EC69869BE,0x103EBDA942673B40,0x697E0D921571538A,0x5680193BB7A20F45,0x9DE88E686F60E352,0xD8B6B002CABE4E36,0x5E7935C09AF8ABC7,0x9E330FC92BA42E44,0xB80D624B7F5A84DD,0x64231D1F29C938F1,0x95817D4C4EFA1051,0x7CC21178E11CCDE8,0xE75C4807349EFA84,0x96F8EF54B354715D,0x576B95601FBD278A,0xA342AB2E2B4D56A9,0x368D657F480467A0,0x4ED8893D52789503,0x6DC25936AED0C593,0x79066E93DA926FCE,0x4AA3CF0D0D00421F,0xC81741B441675EBE,0x80E829B533CB5A57,0x7F89292ADFD5BB11,0xEB9800F3DF143BC3,0xF30B3BD883EE99D1,0x0EC85B3BBE193798,0xAC749EF5D31F8CC1,0xE43ABFB48C83F44F,0xCDBD8628E9E3B629,0x34B7137A5D6DB178,0xCEE84F20A05C4DD6,0xA9CEB8B181AD101B,0x0E8EFDD1F787F3A6,0xE843F05CDD4650B8,0xEF41552811A0F1BA,0xB6706A0C04582CC3,0xCAD17F92AE1BF870,0x6DC54F807C2F35C5,0x4985CA16BA1DDCD5,0x15CCA7D935D5DD6D,0xC99F5929ACA44253,0x74FFA8624DED4019,0x8F317955133E189E,0x09E70C144EC7DEF1,0xE1A51C820C210024,0x48B68927144FCDB6,0x7AAAD8F8A15E416A,0xEC81E13F11D35C73,0x4D2403E8121B9482,0x558E80EAF1A7BB46,0xC1DDAB310DE6D67B,0x81BEA86E5EEE7E45,0x6F73C5ADDA662245,0xC5771537C82032FF,0xD5928314F59B7725,0x224B721B7252892F,0xC3C94BF7E28AD315,0x25A49C737B517E23,0x0B8D2630149E31C1,0x672C7920C2A6A545,0x8970CC1594EC766F,0x93CFB3C9B11DFA11,0xA62A6576491B66F2,0xF87756E0CD87F2AE,0x54C5CFBAEDF20C81,0x1B62661A7B637A65,0xA1761E8FAB2BA469,0x7CC0A5EC365C0C03,0x7EFF87FF5132B219,0xEDD376A8707A16FC,0x7D641D3198EC28B2,0xC4C7CD62602A0010,0x0816F366F8CA9AD8,0xF1AB10DCC73F9428,0x6063FFB4DF5DF98E,0x9BC8064E3B42E21A,0x1D58034E0F33AD63,0xE08ED9D95ED30EE6,0x7E0690D9465ABBDA,0x1C0ACAD6164287F7,0x6801074FE2386CF7,0x8EB2BC6007B151C9,0x82309974DD61FDC2,0x134CA8411ADC7A2D,0x6BAA06A7B4299B03,0xA49ED75221EF3D04,0xBBCB0DB02223F3BD,0xA78148C590934955,0x4B8E596E35AD379D,0x88D839C54AEB7F5C,0xBC1C363910D86C83,0x7E8374961DFB511A,0x20C14325DC1425FA,0x9453E09A44079CD3,0x5F489092E30562F5,0xDE7B0ACC62309F73,0x1C70C6405E77F575,0xF3D2B69FDAC2E942,0xFDCC6BDBF6DF35E8,0xAD4631ED60B22DD4,0xF85E377AC07AB39A,0x2A10C47D5C6339D2,0xF53FE66D49C1BC7E,0xC30AD6642B9C9A5B,0x352E2F21DF1B9DFF,0xF0D76F9E14BC373F,0x211651CF6BD3B1C5,0x4EB8974CAA0058D9,0xEC942279EBC550EE,0xCFF5BF4BFA1A167F,0x97CD6D9D35060ADE,0x4EE9BD70FD29E2CB,0x5F4201B420D9CCC8,0x6D93C9627843BD2D,0x6E76895186165B77,0x0A363195C9EA1D53,0x174286662B469FE4,0x22EB5F92C2132387,0x964E3EA5EA512BF2,0xC0B2D74293FD9715,0xEFD32542CE06B721,0xD830E57823F87CDE,0xF56515B23DE03E14,0xB3167892D20F7DC9,0x4A93AD92EDCA64EC,0x06B71B938DEBA38E,0x67D7D9E71B58124F,0x9E5A290E5C2C4A6C,0x7726142150F4CCD2,0x2D63C1129646529A,0x2622648D445A9BD6,0x47946452E9A89A01,0x530A3565A2ED3735,0xBBEE80F9F7C8813E,0xDE5833FE559EEB51,0xC740D786FF3310F7,0x2C915765A1C17DE3,0xE2ED616C51CB58E2,0x3971350AE8D97068,0x770F0BD4528708E1,0x2C1C9E2420263E17,0xCF9B17C1CF65F28A,0xF40B966288EA2894,0x05F1828FFDB3F450,0x0892B4DE889D5D75,0xEC82401C73714CA7,0xD618C5B54E40DA37,0x639FAB28EBC732E9,0x19EAAA0993A58E18,0x2D7FB7952197ED0B,0x67D5AB1BDF951CF4,0x5CD5CBC6E35819FE,0xD5DAD228A67AEA0D,0x003580CF9435C77F,0x78565E617A3C825C,0xE9A568DAFF6A5204,0x676B2F8784DD69A2,0xD1CB1CDAD323AC53,0x8C55127747F19B1A,0x4C408F8ADAD80C6A,0xD6122C294532B023,0x043CCA81DDC784CE,0x3809A6B20A1F0E12,0x753DF88FBEC0CBFA,0x7909844E30088589,0x1A3F2E4EF923FA59,0x01099FE2C2AF214D,0x03571DB614F19046,0x623ABD858FA68FA5,0x0CA6938B1605FE31,0xF869ECB46D73B72D,0x4DCE5D50297624BF,0x7C18DFD38B3DFB21,0x191F6C13650F96A3,0x9F67E94DCF8328ED,0xCCF3B3E3DFD450C2,0x3FC25C933CEBA701,0xD581CBA0E1AC59A7,0xB68CD0FFC823B64E,0xA411C91229649140,0x9D68E87905A50B9B,0xCC2B49819FF3C51B,0xF13D1DB4AE7A889C,0x824B5784A1BBAAAA,0xC8DE31A01D14935D,0x67E802A1DFD2C523,0xF7EC78D65E2C5576,0x69944960A3858C74,0x8036864B01806E94,0x87F7641232F6012C,0x0703CF3600CE111F,0x8CFF0CBF96C9FCE5,0x64C81BF5C24B51B7,0xBBDCEB9842B28512,0xBB67815B26F6E518,0x2FC979E49A550ECF,0x387D739678323843,0x907B4F0F263DE62E,0x63D302B590CB8FF4,0xC8854B43BEA5E914,0xACF98D2329058FE1,0xD36B44FACCF99CF1,0xC4A9307AFC09B38C,0xB27D42C8CB96971C,0x833EA56FE1CFD5C9,0x7A8A05C9C57F501F,0x9C61A9985A518E28,0x27D353474265CC2E,0xA8A595043E0EAEDD,0x49FCFA9FAA794892,0x5DAA8BC2D5DBAF3D,0x20A1D790A620A65F,0xEAC1B6EE98AAEAB8,0xBDDD4575F2598A1C,0xE03B74BE0B4CF84E,0xE007734F3A6462B5,0x234070DB512285ED,0x58B993203FB10893,0x2A06237B40BE6665,0x0564BF21E7EDC6A9,0x2710FF4FC6E1F8C4,0x269C6D736A18B0D2,0xAE9B33E83448E2B6,0xFDD9517C2EFC908C,0x11E3E4E6A43097ED,0x8DF0A0C80FE8C987,0xB2F107D26409B324,0x6C99E8B2FDAD7ABB,0x16484D9EF38A437C,0x1DC52D7A02402899,0x90E416F1BE2084E1,0xC33A7DC9B7827B4E,0xEF86D8849C360172,0x08E2E4C65DDA225C,0x2020F8A713BF3BA3,0xE98B5C13D597A5A3,0x23E24DB068F50FC0,0x58AFD1C7EF375870,0x3844952FAB8F5693,0x874EC7781D84A958,0x5198A3E3E34982D2,0x57E2CD8BE01E0846,0x993947A97F268316,0x1E58A9DC75611FE9,0x3E03B112F6204AE1,0x082896918052C641,0x3BFF6BC18D81AB69,0xE137D7CC679C749B,0x26F73B866CB87271,0x12744B8C51739FDA,0x5698856216962D25,0xB40C20139042E370,0xA622BA988143E353,0x686A3AC6889ACD80,0x8EB49A10DD599477,0xEEEAEE1BBDE00C78,0xB16F41523EB8D994,0x99BDF25EFD044F06,0xC1351B97F1873519,0x81B29566D6AB71B3,0x1122F917304EE986,0xB7102F83C78B6643,0x7C467470458A3533,0x8EF116AE7F154816,0x0550452B0282436D,0x081BB1E55310230D,0xEEBCC991E3DDF994,0xE0909047D75F6340,0x71BA283731972B1F,0x9573412059CD8995,0xE0DE88CFDCE05F71,0x6D77ECC040EB5AA7,0x6BCA65FFA1449C14,0x485E97CC19AEE215,0x4BE6ECA47FFA5650,0xE947B9FEDC7C9573,0x503A06884642BBF6,0x8294002C845678A1,0x34F97BF4EE9A3460,0x46519B465362AE8D,0xCB31B2A1E62E33BC,0xC9C3B84AB779A56E,0xAC995E4E5D719DF4,0x2AE7BD6C78D43E74,0x77215A680AE0F129,0x03C3B0D8F99DEF6A,0x21C5BB37EA7DC5F1,0x198A0086E90D4BAE,0xA2EC525D50E032BD,0xB0935F6BFAF638C5,0xEBBBB8B569D5BD87,0x6D911E01C9AA1975,0x550ADF6366E992C3,0xB71FC96B2B0436C2,0x7BD2D139A7F69737,0x7FCAD24E3648BC45,0xE7DBA4AB64B7D517,0xF4FAF5D0FFD98835,0x023A32C8763A7F78,0xE89A7173322EA5A9,0x4391EA41E473DD26,0xBB4FCE60E4113C52,0xCA26A079E411D400,0x8222D79BD783410E,0x628BAC3ECD597F7F,0x70AA0684623E8F7A,0xF3604A041290EC7B,0x2E7AD4586B0FC97C,0x4B5CCD5208F673C4,0xF02BE9A5968CB033,0x7C590856649EF201,0x83FF3F7471B39ABB,0xC239D764933CECEB,0x30D9C81A6498770A,0xBE4EE899BE35CD7B,0x3CF14105826EB19C,0xD5EF6400B9C69B7B,0xC457F0C0CD7A24C9,0xBC299CE7B824A321,0x0B24ACC5F4523749,0x3F976B107D9A8A34,0x68933C6CB1D2F324,0x7DE55827641B08B3,0xC61D7819070BD3BB,0x0FBB816130FA7028,0xCAFDF0EDD16D37B0,0x09F449DEA54295D6,0x97A0B97DFB6B9046,0xCC52A636E520D075,0x9047AE376AD9D64C,0x2E2D68F7B3B3E675,0xFC0B8A8F453B4D01,0xC9C277039C0A43FD,0xC559BA348F3E0599,0xBF790E49D519E7A1,0x9F0C25E41921F1EA,0xC6CFDB0547F1B7BD,0xFBE9B26BC75617FF,0x66EDA78DA171FA58,0x1CD825B806A41BB1,0x03BF3ED7E1E781AA,0xB983866B14973682,0xA86E1683FD55D257,0x27CD7953E8DCC921,0xC4C088A326FC8461,0x45E90BDECCDBBC3C,0xE350E90AEF7394CE,0x1613B9BE476C27B1,0x3B25A700258A806B,0xF9291E85EDFBFB70,0xF43D8A711D0F6DD4,0x29F182D94C069A4D,0x37F11BF5915BD555,0xABC1B3F00D07C10C,0x733B4C6291AF63F9,0xBF8BD50BE1E898F0,0x290841A31EB2C505,0xCC8CFFAD6204D107,0xE77B924E6C156B6E,0xBB5DA26EF1CE62B1,0xCE9CBED6A3CD9133,0x56D94754FBB4524F,0xC84E1434F4A2CAA6,0xB70828F130E17ED3,0x989D827F9D1A65A9,0x48526D18243DA287,0x05368EBFDC7D3FED,0xCC1E95867DDB6AC2,0x6F07BBF9666231D1,0xCA8E770BE41AB79F,0xC1675C2261D561E7,0x3B7E632F620CF0FF,0x695731FDB8852B7E,0xB61566426B127A15,0x0F5C8DD260A5DD9E,0xAE3CFD63363B54EB,0xE3694DE3E7A8035A,0x58C3786781D27541,0x87E6DED68C484940,0x4FF73539395C877A,0x36E9E251E8F78039,0x9CF84D8900972C8D,0xD609BAB68B0C3D40,0x030AF0B84853D773,0x33A97E95252D02D6,0xFE584D59B1B9D017,0x77CD2228285B65DB,0x25EEBA3E5635DF25,0x25E5677F28CECC57,0x3949BC3AF70C4117,0xAAB8D878B4D2E8B7,0x9D1B5461BEB4AC17,0xA29040CD94E5D581,0x2127F1752926D908,0xA9D5A63B299459D4,0xEF8BEC47621B70F5,0x2A959275BBB6B027,0x045349CE52A6CCA3,0x92B6BFF179914FE3,0x3CF9F6ED25F8483A,0x8275F23F1CE16415,0xE4F62F336E5384F5,0x3B49D0386A82139C,0x9B045637B425F8D3,0xB5634E2F69C3E803,0xD06CA873F44C36B5,0xFA87D36027B66AE0,0xD6224133BB283F25,0xF5DB0F647D2D9298,0x0383B72618E22585,0x60010D0E6AF145C5,0x3B1B5CA2D9EADCA6,0xBF42E464909AB8C6,0x4DF492AC77D536B5,0xC906330EBECBF4CD,0xD5A179555DDE2212,0xEB104AC1E4056F76,0x8F50EADC84831C98,0xA8071485512804CC,0xC2C3C8CA02451043,0x1D735E162184F667,0x61C785ACC0117549,0xC7B7D5B926F62115,0x73F3AF4B0CA4E373,0x544E4C6FBFB7D895,0x74FE5E83DD6F0753,0xF13187B24E2E32C4,0xE08626A6B986494D,0xC7B1A5FC2F337188,0x3A3685213E0A82A7,0x057DA5EFAE9A0BA6,0x0B058981BB09F50B,0x6794DE9236F24FCC,0x7F3B178F4CC7811B,0x4D28A59B9D432117,0x56A14E10810802B7,0xB9436959815D8F59,0x9339DE19DCB67852,0xA788CB34B4A824C1,0xCE6EE58A2B917E91,0xD47ADF9BA88021D6,0xE2B59F85041F51CE,0xAB5C5D69E2E1A665,0x78B4BE8D037E7E05,0xC148697D725EEE72,0x42BBA2E72F61F97D,0x854B42747DB532E4,0xCD39869001CE7C89,0x4D0E3B795036C1CE,0x5B6F2E4DFDBFBBB6,0xD86D83934BBB24E5,0x4803E0CB319E2F06,0xC161381AAA8C65FA,0x3218C2743AB3889D,0x87440868885CD2A4,0xBD828FFCCF288537,0x758504A0EA16A376,0xF04937CAE2D2E047,0x3BCE329F3B330675,0x74DD47C6406D9636,0x4512711B580AC9E8,0x05DC022C4EC7A9B5,0xCB64B1CC5EFCAAFC,0xE6A1CEE00E690497,0x5A92E920CD2FA6B5,0xAF71FBFC5A564014,0xEF923AE42CB06B60,0x50995D78E07DA1D3,0xDDFB9F6056667785,0x2E3D0282491115CC,0xFC0B75BD8463DD3D,0xAE02EAA861B90B7D,0xCFE92EE771AE813C,0x655444763DF32389,0xE718D622883556F4,0x1FD1927E85B9AD03,0x21A9C3B73C278857,0xB49166C6F8A7130C,0x8FCD963DB9BFBC5B,0x3CF07FAD360EBBFB,0x710EC0027AE9E65D,0x4A080DBFA428ACF1,0xC6C331392A664A94,0x26FF7A7AA54F50C0,0x1E87E66094EA94D3,0x5DBB7D743B4026E0,0xFC951C67FEBCD88A,0x6A8992F37DBCB782,0x2639FDD63F996F98,0xE6B44F4233FA7140,0x0BF51A4D63031D97,0x53305A6D8EC60C40,0xC47137B8044734C6,0x87ABBEF9C0AC0485,0x8C8257CEB2C0418D,0x011E58AC8BF2F8B5,0xB421EAB9811E5F1B,0xE6F43C9A66F38B25,0xAB88F9B9E30C3E81,0xAE9EB168CBDC1228,0xC02B62EB981E2148,0x63B4D019F115DF49,0xB9B93439A3C76324,0x995CD4EABE242DD3,0xE71EE890BA5563AC,0x20F405D0CFC15566,0x662CE6D06356982F,0xB447299AD4EDE438,0xF38F43D17C648823,0xDB2148C236E212DE,0x47AED6C87BA43444,0xF812FBC1C7ECBD5A,0x46872DFE4E1106F0,0x19D6FF0902D4B84D,0xC2B9FBCFA13A783B,0x8B04E8993069AAE7,0x5B70CDDF812FE26D,0xA515DD509E44D49A,0xAA73E8CFC65EAD7B,0x238E67DC3DE10E2B,0xAD6130DD0FE0EE4C,0xD2E78D1ECD033EE1,0xA1E02833A2FDA958,0xFB2E50DDE9ADEC0D,0x978FCD2FF6DBC352,0x9AEC11F84985F48A,0x553BE015B4477614,0x64CB956C99C43999,0x88328B6E040E97F9,0x5058985EA191EA3C,0xB436ABA26E01CD97,0xD569B694CAE1D9B6,0x202B6AD0DEB405D4,0xFE6FF894882B3CF2,0x45E7401DE2624DA3,0x229800863AF80E50,0x2451D5F050454812,0xB0233B6FBAE968CF,0xD64BEEB81E42BE13,0xEF8E2F33582B0756,0x94F0553252529524,0x0C9632B274C2F029,0x00DF5C0EE185B21C,0x7190439CFB528A63,0x8E40E6FA1204CB9C,0xF60D6BA74D675952,0xBEC94C7B6CA72948,0x007401B5974C8EC0,0xCE9032244C4DAA05,0x78318A826A2EA98F,0xCB1620C7A2BF9902,0xAB59B775584B6FFC,0x8FF0AAFB7AA3C360,0x5235ED4E3ED4DD8C,0xB8D3AC5B70E784E2,0x5F45A2C284EBC34C,0x22152F2BB2AA21DD,0x0291150CA5B4B5BE,0x1EED5DA23BB91865,0x940F35278D72F99E,0x27A3D1198172C100,0x75600D3E19B9A220,0x688B85D6C4938785,0x20B1641C29BE34F3,0x09E155EC9F118883,0x8CE90C2800E2B466,0xDCAC303289645122,0xC7E92E7800705555,0x22B644E987798C9C,0x7D1E43BB97A96FFF,0xFACA4D807EAE4A36,0x23D5EBDBBD8C62EF,0x82BE24DCA695EB95,0x2884FEA7A49D651E,0x03F6E756D9E7C193,0xF1B214AFDF70C19E,0x4D6F898EBE8FDDDA,0x4216DDFEB02A6F2E,0x80A30013ADF84543,0x3307F7389876A176,0x820E37CC58065EDA,0x43F08E2526727B7B,0x5908E08C206DA865,0xB646E81D8EF6B6F4,0x1242BF8D23C113FD,0xFBCD27EF310651C8,0x3E9C12C40C47B591,0x3AD7288029CE8F59,0xA53651FF1991A1A6,0x7E352C415F6A101B,0x30B15436970F1B35,0x0922506821D231DD,0xD85972C89F99A351,0xBB2D7D9C8B691B82,0xF75A5E94E3193C6A,0x6C741693195459E6,0xA36FF16176DF4ABD,0x5731C1845039E738,0xE18BEA906CB620E4,0xB539475C87927258,0xA6095A41B2D1FFD0,0xEC7D8C1363699311,0xACCF062244846CF1,0x4648ECDD10C13192,0x278DB457930F64D1,0xA4B45587879C6612,0x7467980CF70B7F1B,0x65465B13682DD3D2,0x9A1F5DBA8575CF62,0xC5D85F5636B7EC45,0x8FB0BBBDF9334870,0xFFAEB8F6C1BF1837,0xE83ABA281FAC72FA,0x1F940775EDEDB288,0xB3D7E1C0FEB84B70,0x1160B620D5F5134D,0x4DD85CBC0731C82B,0xC58B2DBC06FAB136,0xED0EBD7657D8B668,0x9333D6E94A2DA6B2,0x1CCD19DF955E8305,0x55241F18522DD39A,0x7D5334BC0C117870,0x60DD906B0A707CC1,0xC403F2EEFDEC9F42,0x1CADD84490D74DAE,0x9DD96E44BF16BDB1,0x5FEE5636EB6385B4,0xE7F3A3F464F14329,0x6836827783AB7390,0x19A5DB957D2CBE99,0x997CA9110676C1B0,0x7950146E19BAF12B,0xC354CE571C2414A5,0xC5DBC1A33536D49A,0x772AE523F66C2527,0xD89EAE4EEBB6DD49,0xEE538622318DD5B9,0xF653E4843EAE88F5,0xC0F31E5E89A42557,0x47EF25273C9CC746,0x9F7F0F5BCF7A3969,0xD64F6336E5B23E17,0x212BDECC908B29C6,0xBEC7C47D0CF6FD8B,0x0DB3D388FAB25D5C,0x8D12F1B5292716EA,0x8910D097DFE71860,0x6622171B1705D94B,0xD2C8C8623FB6F279,0x85B3C087FA4F2C26,0x147D84AA0AB6D2B9,0x7EB141937B261353,0x030F455DA0B8325E,0xF32388422DD44304,0xD1BA3E213C05474C,0x750408E384D8C867,0xB41E8868BE805798,0x31D1BE7DF9B6E18A,0x5EF18EDF20589B62,0xA696E5676D9CCCB7,0x4BF4294A4DB93DFC,0x328B6DD96E2C35EC,0xAEE2A134D1A032D7,0xB3AC761148FE38A9,0x3EC0800C64B2AFA8,0x51CAAA1CAF379F4F,0x56F327CAD43CEDB1,0xC0091917F7B2065B,0xDB70C40A68F63211,0xD503CD7720F383E0,0xAB59C2213CE66747,0x1A81E4AE4826F683,0x579F5F8FA82B122C,0x6EE40925E52CE467,0xE5F566FBE7DDC1ED,0x20F8CEB74A8634D9,0x737EEA7993CF8BEA,0x063CC2BCD3B8F203,0x734F1AE34721F05D,0x4971B373ECC738E3,0x4A22820CFF73A4B2,0x2D7DCEF992BA9850,0x88D16954A16D7EAD,0x61A1A8ED59DDE85D,0x3934AE149EF5C188,0x54D03FD6F924FEF3,0x1DB2C570CE27429C,0x886A8F858A80FBC0,0xA831FD43D7583650,0xC3F8B59B1CA07BAC,0x1E8B6FC3FA01167A,0x4299CDEBF80279DA,0x3954FDD784CBB999,0x376DDD90215C7BCF,0x2F36A8652D7C9F68,0x905F239946B927DD,0x43A08EB9ECCF514C,0x89E7CC80B40340DF,0x9AD244966A5B248D,0x077132645D53A513,0x35CAB51A87695723,0xD6259AF81EF6F7ED,0xF3F3A1F0BBDC7693,0xFB7D4E41D5335EBD,0x0E8369F9ED319CBC,0x039E9F106A7FB0B6,0x39E107F16CE7CEBA,0xB39B42DE2F0AC5DC,0xE4A6F569A5E92B3D,0x7A423DCBFBAB461E,0xAC6016C7A1ABA0EF,0x43ED7BC7124F2985,0x3073A18EDDAE34C3,0x97A8FF9877187D18,0xAEF9DBFEF0E9E8AC,0xD0721C01D278C65A,0x462FBAA367376E35,0x14BF32C36D176458,0x67C6CC18F048F4AB,0x48F89DBE066AD0F9,0x9DC26E34F3F3270B,0x049CFFE0B3CB466E,0x5DF9ED9C5D70FC55,0x0DC2BF5AF77A83B0,0x40AF8F3FA34360A7,0xF544D261581966BF,0xDB6319BC0336B4ED,0x54F2F13CDE639EC4,0x080ED4BC1E0773D6,0x2E30EBB01B769E71,0x22E323EAE76F9386,0xAC3FC80C8A2CAEBD,0xD7F530AE9B71093A,0xC3CD59E13205EE06,0x3FD8D61431D439FC,0xBBC421D902E66527,0x56A58260E5F61FAA,0x481E25851D23F512,0x05F377E0A0489402,0x98B37298372A2DC4,0x21B0F14CD5D72B68,0xC3205A2A4C906FD0,0x72C86B317C05D748,0xD44CF02C6ADF3CDC,0xCA24D62C4D6D92E2,0x7F5D1FA3D5668C33,0xA80EDE09B52199AB,0x1C4D6B290569AB49,0x0142F51F954243AF,0x2C46BDE785792907,0x7768DD6DBBE9697B,0xDFA1C41CB219636B,0x29890C5FF841F8A7,0x3A4D50AE8794013E,0xE6D30EED7569B23C,0xE1F807AD3E469DC7,0xDDFB837E031B1D3B,0x097B92092AB6ABCB,0xD4877880D7A57182,0x7D28E61498FD426B,0xB928C680C6EE248D,0x459899AEC7F57BFA,0x0502DFE576F36983,0xD09DA51FD2E1C734,0x0502B32CCF5D04EE,0xE3AB48780C6A50B2,0x8911EE3D9169E9B1,0xB4389070B31AA793,0x8E9EFC0CC808FC4B,0xFD331AE14EED84C5,0x566F9B26DA3B9E6B,0xA5FC7295D6730878,0x48C11FA2EBC9BEBF,0x174E246AD9E5E987,0x0BCAEDC324D997F5,0x4792EB2DA01521EB,0xDF4CBF1B13DE3CF6,0x842024D946841787,0x316064A5D49DD977,0xFFA05E002D76990D,0xC251C9704EE22680,0xB59A510F427390FF,0xA40695E26F7B1DD1,0x3C63AACB259D010F,0xE6ABD0516ED9E4C0,0xD78161FE4145BD34,0xB2559E168ADC132E,0x259A433F8E1A04ED,0xD7238915CC92A091,0x4BF536B66CF5E7AC,0x2A458A74F643E4E9,0xA3BB2DD6BC4642BD,0x349945246C3BC347,0xB3CEB93CF2D891A8,0x082FDF14B176E0D3,0xF2D2D517F69A94C4,0xFB39ECE12B56B1FE,0xEC7D278382ED9790,0x470B5A963C45A0BB,0x5A6DC34615A6728E,0xE94505252E115421,0x0B58AC108E7CFB08,0xF49FBE0553F9B6BC,0xC64A607BFA5D25F9,0x5FEFB6A86BC37994,0x2D71B5720FDB04D7,0xA9629E045EC84CAE,0x0EB1BAA1139DBBA6,0xFB62D66E007479A9,0xD0307053E609D232,0x7A1A681AF58BB47F,0x5299DD4BD4088F00,0x6432F33C3FB81613,0x974D98F6D71DD371,0xF191BF41B6240762,0xF671D194DA3D18AA,0x453758D31A7CC312,0x35F3AD1CCB57BA07,0x636FAF7CD75F2254,0xF64D56DAE37A4211,0xF5A4C0ACE512808B,0xA596AA7E76D84ACC,0xA94D6AAF742F382E,0xAE0C5EA3116C36D2,0xF3CC9109F795A387,0xDC170F86AD86EEAA,0xBFADE16A09D9C4F5,0x17A59B01BAF8E0EB,0x5CA270827D56ABFA,0x9B5EE42354BF306F,0x81003AB5AC8EB7A9,0x42CF5662C6396D82,0x88866D53CB871A8B,0x96641EFFF4E28B21,0x85C60D2A2762ABD7,0x069C8BBC11292D1D,0x2D2BA92643C5398B,0xA0528A50A467DE6F,0xEBC6906B2A278E9A,0xFCE72EAD1268BF31,0x8806E820548785EA,0x3FD7FA89FEBC4F1B,0x6090C723625E21E4,0x4488CE488EFE8B02,0x5409BECF7FD741B8,0x5510CCFFFB54CDD4,0xD592D962F4631D86,0xD32167A21FFA6309,0x5B5776935291DDC7,0x5535F5982645C661,0x399F9D87C5E6CB3F,0x4062D207DCF7DFD7,0x857BEAE805529A89,0x0FAB3A7696CA444E,0xC0011E4D2D97AF3A,0x2DC35EEDA892AC50,0x486D74EA06D92572,0xFF99DAF4C5040742,0xB1312B41838E5B7A,0x008B6C3B4B556BE4,0x70E0207D62288172,0x0AA60EE9CAB13086,0xFE8C2F05872DEB00,0x08D1D5167DFE9DB7,0x531ECD2F80AA2A4D,0x2B540EC997EAC9BD,0xA8195E4692BFC696,0xAAC01C5AB7F98398,0x97555FD45C13250F,0x574C5E2BFFC2D1ED,0xEC107E699704A6C1,0xAFC3023C87B7724D,0x371123A60B9FE645,0xBC27718C18A39546,0x3A859C4B5545A304,0xEE4E28DDB958661A,0x82E494CF8187EE4B,0x73D5EB57E9CEC912,0x26D326D89D9A9221,0x52107E5A74705831,0x7CE28F72EB953D33,0xFCBDB552FE5F89B2,0xCBA990202C7C5543,0x2E43A04B3244AFAA,0xBA1BC4B23943929A,0x322815FA8DC18AE4,0xA906FDBB67D1B0DD,0x10FA3E601A7D47DB,0x5BAA7B6E5C78D2F9,0x0DA3FE1BA6083A70,0xE3FEFECD5C4A154F,0x2830CC7B36081128,0xF913131883689B2E,0x4C13B30B95A732B7,0xEF9EC47644439364,0x9546EBD6CA95F443,0xA96C0747FAA73C77,0xEF712969EB5CBE83,0x3C41D4D9B4F43A05,0xCD2E8ED41C2094FF,0x996DC261D1AD79B4,0x6029E83BA5E10E82,0x45A2F9DE8BE41280,0x4466132017E92E5C,0x2A1012BCEA71693A,0x5538962105AC1D80,0x7ADC23551BB0C6F8,0x1F4DA7AC5D48A62B,0x5ECCEE04009C83B5,0x1C5C0D75C9B6508F,0xB939EEE4CC127034,0x896DD04B06C84A92,0x9852DD288BAEC6E7,0x87D618ED948116EA,0x24B1EFF04C2C60AD,0xACB9702A19E52C74,0x11BB834B98E034BF,0xDBE0CD9CC9FEEE03,0x6A13B5BA4F18C44A,0x505E3CFF2CFCDACF,0x16A5BC068D562572,0x2C86BE682F22C4F6,0x81832C21D47A86A8,0x6C1E9948AC73F944,0xF36CF641CDD49C19,0x9ECD2932A0E513B3,0xC5005EBD02D86EA2,0x4CF40D864EC51F87,0x2908A1733386F443,0xA57AE0B29E4C155F,0x31FEF6C5ECD7DF95,0x1683504BB133A1F6,0x1EE0517E02B4E75B,0xF9182863EEB9E0C5,0xBBB433F44A6B832D,0x16519E0EE0E78280,0xE11963C5EEB371FE,0x93951F68D08951D6,0xD3992F962D3CABC2,0xD9254ED980700215,0x59AD4E1D0523BE98,0xDEA3E6BB6CAD063E,0x56F0D01E14E09413,0x8DA51780057C750E,0xCE733A452B78BB7C,0xE85C4E94B23723B5,0xCE03EC109AF840D9,0x7B017F69196D641D,0x6FBF5AAE312422B0,0xE4E1B0051C422997,0xBD564E43D78AAEE3,0x199DBC0BE1C88AE1,0x6EED4A4FF6E90F41,0x55913DE53F9C8648,0x0A07FFDC86D1AFCC,0xD59256339E1E438C,0xC85E41A12B3F20F6,0x03351767273CEE12,0xBC321A125665EC73,0xFDC3440BEDDC10CE,0x83CE17C9B2F8230C,0x959EB4EE72770920,0x00D823AAEEF227F8,0xDEE8084F7AE18E9B,0x374E7CA7A47D9AB3,0x0869DED284584B65,0x1BC8C868E2607BEB,0x2D14BB3F1BE8EBFA,0x217DBC0289834D71,0x54E099F5A20519CA,0xD7C35579B111B071,0x25005FB806D56F00,0xCEDA51A30C989A81,0xDECA1E01901A3B20,0x78E65EE0F101D390,0x4AC89FCA127D44A3,0x7CFA7282ED244A42,0x22552F9385C307B3,0x8CF5B5AFFD4F15A0,0xB08A53717F4AFAC0,0x13EEF5EA772CF78D,0x277C3650C4A992A0,0x6FC82BDBECD705DA,0xFED879A1E6F39679,0xED784EA72F9EA19B,0x02921A4DFE85C83D,0xE6387866E44AB5F8,0xE3F773F4C993F372,0x21169373EF383E29,0xD97AF2D498A61C3A,0x35CDCEC83EE4DE3C,0xBED83C99C7911887,0x246A7EF490069DD0,0x2F491063EBBE1D53,0x1B0016E9A9D7789C,0xFF6010D24AEA0C48,0x76FFFE0650CC0DEA,0x24C779021318593E,0x15335BB2E7607F52,0x9A14FE8E9C741296,0x49E2A2132796A737,0x6BF9989DE55D1F3C,0x29093E7A2E92AC48,0x9F2E66DED613B057,0x575677D60357A18E,0x7781F17E500B216D,0xC20B1C6341D0506D,0x1274C909EBA7C5A9,0x123A8277F3ABDFC4,0x406246207FB73587,0x5C942B92B0065B06,0x2E7C3ADF9C0738B5,0x861ACF7AE225F634,0x8AEBD5AFDFF32D7F,0x29B411B614725A04,0xF02BDFB21437D78F,0x6C4E6D9D800D5F49,0xDF36B0030EAD4469,0x1EAFB08093A4468E,0xB952F6CFD322ACB3,0xBF2CFA993E490A35,0xEF0423292732D1AE,0xCEDC7CF0E635DCA7,0xBAF525EEAFEB1CAC,0x0D5D423151A3D260,0x9DBB14381B49AAFD,0x49A5AC2CF25C6EAD,0xAEFBD546EBED6907,0xFA7AE50CD85B9ECF,0xEEE5A2696F9A16B6,0x757E9369A244B051,0xDC3ADFBF3A2DBAAE,0x3B177B00CCD90B5D,0xD2F230FDD5370043,0xAAFA31F0FC31682C,0x897702119C969E24,0xD87925FDB68553EF,0xB63F702C96E9C4AA,0xE4AC668EBA508D89,0xD5A8B46897FB8861,0x1913AAA58AE1C9A9,0x2AD01E69F0071372,0x649D311F6D30CB98,0x88E708BB74820058,0x3B2EAF1ECFEC40BC,0x950B76671D7918B8,0x9C084156E634FF5C,0x90A916BFA07E6EE7,0x470F92D089D4B183,0xEC94C5F9A1B693A6,0xD29DB6159EAD9D31,0xCF77D77D7DFA48F4,0xB84EBE38EEDA9B92,0xC3515C7C6895CFC8,0xAD9C00007CD0D2DC,0x3E17317E4EC2E74B,0x2AB010854C36582E,0x79912EC51D71BD66,0x0E72AE1FA55B74C4,0xB674CDD3D9852D72,0x86C3B0CCE8B0172C,0x27849963AE919E1F,0x0F61B84E282653B2,0xE815492F5E5B8423,0x141C6BABC245D89C,0x505A3CB8B77DDC27,0xD7F58B2BA0F68A5F,0xC371DC65EA270CD3,0x0C46169DDD01842E,0x1298D8E18A8F8FD5,0xD58278261260CFBF,0x2E419D12C6FF8C38,0xEF30024DDC5C4BE1,0x1596BB21913BAB7C,0x914A8BA8F8845D3E,0x2522E4C04DFBA7C0,0x06E4697506698753,0xD14A8BF26DA2A3D4,0xEAD9D0B8C6781098,0xAAEDFD34707E0291,0xBF49F8261730F4D2,0x81D095BFF01B94EA,0x7DD7ACC8485A76E1,0x68CD470103DBAA26,0xDF8696439BC4065B,0x6F6BDBF9D0FB6594,0x8F17F3E8E6104BBC,0x5597893B11DC0AF1,0x400F759C1F59E5BD,0x769C2851802F2183,0xD2688793548A6185,0xE81C47496B16EB79,0x9BF23292B56FA125,0x78641302CAC7B471,0x4E8E5106EF872167,0x41EAE0990D3AFA56,0x843768D0B41F5517,0x71D0094E1459E209,0xD2C1B40F8CEB7186,0x22A61D51F6817156,0x34BB97DCBD91F77D,0x2786E9319688C506,0xB0E22DA5498FD3E5,0xA3EAA71F3CF27AF9,0x483BE75F439F700B,0x6B9D8E6D13EF48BB,0x2D7E6F3DD4E73CF5,0x089A527DCDDCCA6E,0xFDAF11FADBAFD45F,0x116ACFF7031564E3,0xF3D7C9729E761728,0x0ED770AF87BA63D2,0xE07F651DEBA1660C,0x3CB1F80053CCAF77,0xF9EB9429DF511E5B,0x10FB765372ABF342,0xC94E32D59DBE610D,0x1D8DC4650CB05A5A,0x970DCEBAD6ECB337,0x40E8954685D7C3A9,0x982F6802D03E066E,0x3264321A54C56CD9,0x5AD8F3EBEEBF2E8C,0xD02817537094035B,0xBBA3C31E474761D2,0xD612673679083E3C,0xB8EB2FB2BE2ED31C,0xA52EC68312957F12,0x3DC98F1C30C78D9C,0xA1B577284D2DC982,0x70CFA450A801B1E1,0x43DDF3C1DAF30585,0x48CC7E6C77B112B8,0x647FF1AB8AFAB0D1,0xAB66B236A750E127,0x3C56CD5917B99E0F,0x9DA3B8059B943ECB,0x1C9833B8C939C677,0x95715CAB90159ED5,0xD703A5FC3525581D,0x28FA642D0469A69B,0x2B4E3A4E0863FDB3,0x48135EA55CE3459F,0x60F196A4848059D3,0x7BC991778BBE7BD5,0x27E35FF20C4FFC2D,0x453846F8DC692491,0xC224F7996B15D6DF,0x16F6E93E5EF5760C,0xDE3D3C07120D2595,0xDEB0E7E313E21895,0x9F71C736E78CCF5B,0x6789060909D7C7EB,0xBC19BB57E262F177,0xB09C868ADE4BB7F3,0xA688D354FB5E5F52,0x22B1EB84A64DB20A,0x86311B78E2D0D1D1,0xE027AF5F97ACE497,0x3A697212A887A05D,0x081631399DEED3CA,0x0E53BE9B5FA431B0,0x8D808924EF525673,0x4C4382C7BB7611E3,0xCBAA265C5D23E787,0x9006ACFF2DD7FC54,0xA21BC548288C27C3,0xB5D57A1F630C4318,0x2E124A906A90A3F9,0x39AA529C1BDCA6B5,0xFFA0F4302A21E5F3,0x4128EB22DCCEADB7,0xCF6015A72CA1DFD2,0x427807815404E670,0xA0766534DDD1BDE3,0x7AF75ABDBABB32EC,0x344A49A14E7C45A0,0xBE5DBEFEC14DD64E,0x9CD4217235717E8A,0x71A17E8967F96E2F,0x01852A27FE840D5D,0x79D802556E375F40,0xD329BD0B1DC8A867,0x417083D3303064D2,0x04518CD3696C77F0,0x5A9283AB11E60298,0x879A5480396DFA0F,0x6BD0DF2ECA0103AA,0x2E0338FB0E1E5BEF,0xB5A102919468B762,0xE1C9696B25AC6FB0,0x337E520685E17084,0x7FCD030B019CA163,0xC7D58F9A1F2B5264,0xF8030EA8D44E3C7B,0xFD5B45A17A8DF915,0xA8BFF867D119282D,0xE5E48E0AC8ED6AE0,0x0D3BD7635EB125A1,0xACD1E903702FFAD7,0xC2DD3C937AD4C0CD,0x0D6FBA017BC0E0E6,0x9E94E99B82C9332D,0x172456DF63A6CCA2,0xCB78120E698D10A3,0x66EDE15471AC65BC,0x789404F0E6416F2A,0x0F3E2B5E1CCE4B8B,0xA284EC3ED5388928,0xC5723D8F62655E03,0x71301FCC3FE9C79C,0x1F61696F6BE2C70F,0x259F40C9A4F0D460,0x91573F94877D124A,0x86C005DE5B95147B,0xF0184C0A60D21924,0x8E463E316B4189AD,0xECDAFE9695B2B460,0x840F629688A70281,0xB1BBA75B576CC5E3,0x2C7417BA690EFE1C,0x5CCC27A62432168D,0xE9CD2B140CC05F05,0xB5C3B283C7B3EBF1,0x82E9EB48A4F444B1,0x0B526ECBF61F3EB8,0x0362AB158E7FB2C5,0x01969C7E76945E6F,0x1E805F53922161D7,0x29E4FD5FB1673274,0x38087BBCA6D41C4B,0xCAA9C3AC2CD33D97,0xE99AD91FC7DDE186,0x829E4191454785EA,0x10E1E5F644C4ED71,0xB9BAEDCCA1A20E69,0x3493451BECA8CB8D,0x4B17720CBEF28AD8,0x6C67EB640ED2D15A,0x16FB1963D0953FCC,0xD1E905AABD2C6804,0x240A85CEC4356693,0x157649416D6F1359,0xB0BAA9014CF7FB32,0x1468D134DE931104,0x7D20881BB7612303,0xF98F8120C65F8D43,0x5A8ECD579C9F29DA,0xBB70D7C7C65B62D7,0x1F752C0BBA5E49CD,0x5F762204CBC7FB1C,0x4656F3CDD8FA43EB,0x639943CAA60282E1,0x3A140E1A0C5DCA1A,0x3CAA5370499442FB,0x1967ABC9B381BCC3,0x3F692633FA223583,0x66F1563C3C5672E6,0xA7B9CAFCBA4DF4FA,0x2FCD7BEB4346E833,0x3648A8BC72522ED3,0x7D53004D081DB8AB,0xDA3C9EAB133657A4,0xEE9FBEB2026A4210,0x93ACDBB89B58D5EE,0x67270A8D966705C7,0xD12B4E54C479C350,0x01A7168BD58C6F52,0x8EE6BE4D9C4ADB92,0x14545B2EA361CDDF,0x60C9702446923329,0x8BE28D43FA8B5960,0x5F5DA78E50876FA8,0x0C0CDCA809515A15,0x9B404130DE05EA28,0x273F4F6BF21A982A,0xD50BA8940DC2270F,0x7FFA63B6F3B548FE,0x2807E7985BB7D6A4,0x54E9A540588CAE9C,0xD667389613EB3CE9,0x3451F32FBDB0C2BB,0xCA9E089195BF8313,0xBEC0A23DFB610D02,0x2C6085899EAAB43B,0x3B5E12857F2912D5,0x931F84E10CAA44CD,0x95C749C763E05656,0xB95B60A04F855996,0xFA1024262A80CC4A,0xFDA76D9D49065B85,0x6C847945B83C8AE1,0x69F9D1A75973A816,0x50BFA3946117C875,0xDDCA7373766329D4,0x72E76A9BC03278EE,0x19E1D1B681B63095,0x28FFB863CD0DC633,0x7A41C2A2D1760C82,0xB9D8C824FE1154F3,0xD2CE70E89997609F,0xE90A3A4223B2911A,0x5A4E6DA9E5867851,0x94AA4755CA27396F,0xC624C6AB2636737C,0xAC611C1928B94B7C,0x50DCF18391C3DCAA,0x3BCEF230A6BBC4C8,0xDCBE7AEC12707073,0xF8C34A4604C06791,0x3C8E2EDE73BB7BC8,0xA7FBBFDC02263E2D,0x5F35ABBBDDAC1054,0x7AAE23A7A2F5FFF6,0x9B720CD092C99CA5,0x3D4F637561ABD415,0xB8C4344F8AA21A4E,0xF0E8E95C1F337E7E,0xA8051A9EA92E390F,0x996A998BC5C76949,0x22F5E0EB2AFAE91D,0x719ED57BE18BDAC2,0xD8F810628F1D6D8E,0xBC6F5B8E4FEC3D9E,0x946AEF4DEC07069F,0x9FA0E5481F638D76,0x9BCAB5AACC581408,0x0A4886BE5D850E59,0x7C0BDF9159E0C3EF,0x29311DBC40823567,0x1FF73DDBB786E9A0,0x1AE902E0BB9A3A02,0x3C6420A5FD72F597,0x70E7C2FF36A1556F,0xF1F90D69D3DBF0CB,0x2210864F342E91C6,0x253B650A102B826A,0x9FEB846F505358D4,0xF55C7EF4F8EF5DC7,0x1A0771D7DC1D35F7,0x2085B941FD6B21A8,0xC37345BE9E027320,0xC3BBAB0DB675273D,0x5EA03CE292D570AC,0x6C3D08A100C5E125,0x7B6865ED65354538,0x269E6FD78B282AEF,0xD131DBBC62715CDB,0xC361D31D803BFC52,0x778ED5A6BBD8044E,0x0C1BDD6C1CA2FE8D,0x6DAE2AA93FAE7544,0x335FA95E31EA2C0D,0x045F672D603B9EFC,0xCFA5FE12589A9CBE,0x25F6A1AE9EF9B09E,0xB266C92D4FA92E82,0xF921780CDD562E56,0xF19B6E3E055D4990,0x5185486D734B8D77,0x592D3CA38182EF19,0x32B36248219E9913,0xF27129AA064EB414,0xAB6CE7EC451E0AD6,0x3195144833B369F7,0x8E7FB3148154D050,0x63B41DB491AE7903,0x8BA85F69A4E7F3CE,0xA52BA136EB565EB6,0xAAE398A91EEE5FD8,0x9EC0FB44CC910BFC,0xA82F98BE639B32DE,0x73A22FB0B5684973,0xB56670514412ACDF,0xAB0A5B4A3A1D9778,0xEACC9F4972A9D301,0x74927E8558E05614,0x4131BDBC4D274A9C,0xFCA6338AC0572AA7,0x9A5C5C101BFDE64B,0x0DCFA69B4DAB2638,0x4B0EA63C3E06C03C,0xF7A0767853D7DC2B,0x1C03639270F361C7,0x823D81C436F1DB53,0xB0D6723961934FDD,0x00E46A70B7D63382,0xC31D212B7A5DD244,0x58CF13263D7149ED,0xF18A9B7123361E6C,0xED1DE0CD9A1D18A3,0xBDB7D338287F112E,0xD4B32D24DB76C2B7,0x44FE75A63BAC26C8,0x4E47965007D4327B,0x3D5D6958CB95E25A,0x4892627DAD0F011E,0x713169E462F63F00,0xC916C3505FC5A693,0x9E637AE5C5641FB6,0x12E579A673B28428,0x0D41B88FE80C33BF,0xC3F32442FDBA5F1B,0x142B30B43149C5D8,0x24C42937AA4CB4E0,0xA08A8127B88BD8A7,0x61A356C974D9C9A1,0x7A7F5FBC7D26AE05,0xD211C7A084D189D0,0x4BA1347C5BFC4F7F,0x06D5E93A41B3FC42,0x78BB85BE23CF8560,0x6E4D5C680B46795D,0x37B7E5B9DBBB37C0,0xF36DE71827CDF167,0xA7142D26259381AD,0x4499B2BD8B11BC68,0x6A2A2752E4067C0B,0x27E4D486B9080EDA,0xF41B7D717F0B5023,0xFA98D620117F7588,0x77414CC8C4A9EE79,0x36D65921B7B0C6B0,0xDEEEE2EBF50109F6,0xBF6C1262D4590311,0xDED09DC346AC5D67,0x9E10F33E0E34554E,0xE9FAEDF8FB8B3033,0x70787C1BA64D61EF,0x2DDA427DB21A9FF6,0x76D56D3143149849,0x313AEE032FB4F945,0xF443D36C967AFABA,0xC8FCC03B39260276,0xAB89FC54401E3663,0x8AE9C99499E66D92,0x5155AD3395810A0D,0xF31EBD36D70AEC4A,0xE326ADBF173A4B45,0xE330F25DE7138C15,0x5DD768AD0D29F4E4,0x6B1AD2B302FEFE6C,0x6AFA441AF2CEFC92,0x2FC7E62FA357A264,0xD3A6087D5DF02A05,0x6AA45B6A92A14FC9,0xAC079110C27B1B2D,0x7389136FC67F5441,0xA57946F9AEBAFDD3,0x6D36A4D744C2758A,0xDE2E88B5DCBB95AF,0xC391E255B77AED89,0x5015038273AFBA2A,0x82A2483E1D497FFD,0xD6CB4A750FC3F3BC,0x9031255167F56CF3,0xD16A7155FB21A864,0x9858257D749E5E20,0x1304987FB66A265E,0x7F54FDD482E1BE47,0xD99D005B1EE5BEF9,0xC5548C8B0055D30B,0xD2A2798E0818C02E,0xEED3CAB4601DD2B7,0x38895A85F07CA564,0xE555673161077BBE,0x71B43C854B0286A4,0x15244DD339058539,0x8A7D867D3FCAFED6,0xA7BFB7BE625F1DF2,0x77636711CDB51914,0x808705EA283905B8,0xA45BDEAF06874F7F,0x5DEC6EF680B21397,0x9F87BB3E3BBA610C,0x17DFB9B0C579BBE7,0x42D161B8B951C55B,0xED6F3950E72EBF3D,0x1782AF1A466DB86D,0xCCDD270962760079,0x7399696615979300,0x98660C812FF71605,0x1056BA502595C2CE,0x53A41DDCDD4F10F3,0xE3287317D9897FCA,0xF19947A7943A3093,0x72D4F9F42B41EFDA,0x94DEEAE7B19256D3,0x31D1D9D4E6E141C9,0xF5CE4315674E78E1,0xC5A00DA0C32F8448,0x177445BEF16AA6F5,0x7EEFC428B8EAAC77,0xB66A808DD0C06080,0xDCC8974591E944C8,0x2840D14D150D6EB8,0x03C7462B1081BA37,0x5282C7C987105651,0x3D4E5278E4CE55B1,0x67443FFA158DBB2A,0xD22A8404971B61E0,0x9A0A232E1C1650A9,0xF6226F8EFB581521,0x421FB75E6BFF49D4,0xEFA9C93F7762D244,0x7A4C6C3A72C85250,0x241FCE28C78207B7,0xE6DC06F95739E003,0x0D0653BDA673F061,0x8376E398231018A0,0x5760DCA95C6777B6,0x11342F9BAB0A0113,0xEBB29CCCC36E242B,0xE44598682DFFA5F2,0x5E953EE8FD6F355F,0xFB6CBB2AEB241F6B,0x5A90138C4EFA32B1,0xCAEF77F6533A426C,0x2F10157129C2020C,0x5775C39F6B76BC87,0xAFA836F9327E331D,0x5FC751E327FD9D1C,0xEAB82B7B08842D59,0xBBCBCD7B3D4A6D73,0x50F1FB0283A95800,0xE691227E96ED5DF5,0x41EBDDFEABE33FC9,0x5F77382972F14FFA,0xB1C44819D35BA167,0x203EDF48FDAB903B,0x888005C729D468B9,0x73ED0DC600AF23F2,0x5BD066C998A07D7F,0xAA76258C568B41FC,0x29D7685DD7F181F1,0x574C73694AB1ED12,0x66553442E1F9F8D7,0x6B8B4FA0382E3C4B,0xAE3E13A171F1E730,0x25609D01CFC0755E,0xE0E7135EDBE79CD7,0xFE14C383F3E4E71F,0xB48EDBD8B0A786E5,0xAFF5FD02543DF15B,0x6A136CD11D69F8AD,0xEB3007D28798AEC5,0x90B8F181D7472A00,0xC5F8E23D9453A674,0xBEEF435838C0FE6A,0x96D0C5E81F765F57,0xB708F327E8B248C0,0x8034457754ABAC87,0xB0C59F6E5805C273,0x219197CD501AD616,0xC76CB5D1C232C836,0xCABDCD8D94AB6D02,0x16D80F8834DA2E49,0x0E3EF7C0E0E94D4C,0xEEA74A54E2170D4F,0xDB06A1F34FA44B8C,0x9A46A0DFE3021577,0x42AFBBA982159935,0xB79F846F5B985489,0xBE64C07C391931B8,0x549AA8E63E22978A,0xCC2E6AF2E4A62A6F,0xEC187E4C28FF1E09,0x7BDCF453BAB12B42,0x45A088BC7B77E06F,0x5D4E52E1686FC1D7,0xC136A9077C1A7C3A,0x55DBA0584CF5020E,0xB1763D36CE606160,0xBABCECE939152CA9,0x03E7170AE1C7590C,0x9C32C9EF4F69E2F6,0x221783BA997A503B,0x69CC2727349A4C1B,0x088923899013DF0A,0x7452C20DFBBB144C,0x28EB1EC71AA087D0,0x3B609649BAAED5A4,0xEDE2F3F74BF38A9C,0xAA888A5A37C7E5C0,0x05B2E4C0110B9A3C,0x027AF55AA8DDAE5B,0x207725F77F73C133,0x5EA7D63C0464054A,0xEF1AAFF1D1127F59,0x2D1B09ABA510D04F,0x1C3E36684E99149D,0xEEB72BC7B2DC22CA,0x36882689A03AFE6F,0xBC5F7736E7B8A64F,0xFEAAF0CF7D8427E9,0x02F20757BE06B1E8,0xC8DFA3AA8BC65330,0xACB5E51933C5D0D8,0xFD5CA4F4FFB2B560,0x64655B7A92BDF594,0x4F222CD1EA89F72D,0x64F5BBBDA95F1E93,0x55E0C48912E41AFF,0x3738C94C5A4A81F0,0x188008B84384130E,0x6D27BDAF21DFC7AF,0x24829BC3B0A0D6DB,0xDC79F967F9DBCE43,0x3B630BE7AB5A813C,0x23B74626B3ABAB6C,0x45F6E6540D96B322,0xF11DEDC78C8F9610,0xA73929D77EF58642,0x6A016AE0FD45CC7F,0x05C5624C0845331D,0xBE5C06F094B64573,0x9DF8EA409FE842D1,0x18F7F6A8FD7A2CB7,0x8B7F2BDA98A5B90C,0x4CF57541422D6E2D,0x5D81B3BF2753F4D3,0x98E5AB3A1EC758EB,0x8F216CB8D69B3693,0xD4C5D62E0D4E2DBE,0x3D69A7C2A0F97847,0xF66C66768298B239,0xC76E056D940C9999,0xFD09C5D384AD214E,0x654A6E5DCDDBCBB9,0x7A59C12041680058,0x5B70CE6EC16BB71F,0x5ABB11BF0BEAAB81,0xC745F958F96E1C6C,0x258BEEAC95B37169,0x5D33B126B5AF6FE9,0xA73FE48F79FB7875,0xC8B5F6189F0CE123,0xD15A8C4519981431,0xCC6683E97CB7EA0C,0x0E02E7EBD58ACBC0,0xD0375FB8DA720E88,0xEDB65CB505407B53,0x48B68324CEBE7330,0xB417B2A70C3E90C7,0xA59C37AF18F603E0,0x5754E7DA8CE7C50C,0xDC3061EF4A0557F5,0x674101A6ED4618D9,0xF8AC858445E775DC,0xAA50B4F9FD9ACE5A,0xEA54BCF652C752E8,0x56AA042AB3A01346,0xCC5D70B654C6502B,0x04860FD50DBF6B96,0x27CB9E15ED5DC07F,0x726E1AC3FEAE7E75,0x1A13163B888B51AE,0x39BD8BD80FE191AF,0x78035ACFDE560AEC,0x0C978503255C5FB2,0xE2A6B67513BD5367,0x63CC5F815D67ABEF,0xB2744B10EF672A24,0xB1F062233C4C3C7D,0xCFF8E941C2A6F796,0x2E01F15CB1163EC0,0x238808F6CDC609D6,0x529E72ADD0FDA9C6,0xFFA0DEF0153EB030,0x3876222B7B0FD793,0x57DB3FAE5D81B668,0x0C31A3DF9B1EA018,0xD8618DAE0AFD3685,0xE9F868F722A6DFC2,0xE90F4C7A38168548,0x35C09C198EE2BA74,0xDB3F02FFCCD763C3,0xC145AF437A16600D,0x7EF64593D4E44BE1,0xF2C56EA6F391E09C,0x1A88D251328A26B0,0xBEC646D92EEC9EE1,0x1E7A5327230A7183,0xFE7FDEF11ED581BB,0x779AC2925053A3CE,0xED16766807B55449,0xF8DF9BF9C2B48DC2,0xCB908E969FB37C5D,0xD22C10DBEE5AC33D,0x13B24ED32A014B22,0x7FCCF01379F854B3,0x3D6BACB253459EB3,0xD73CEE849D118D7E,0x71472FD146E64D85,0xC69FF2F670616A51,0x890F80292F6C8D4F,0x6D12C6B8E721B08C,0xBC77218A4B895E60,0x416A07DAFABAA2B0,0x80E61C2F5D72EEE6,0x08FD30D3D121C5F0,0xA5B0C83A5233B284,0xDC1784F858E33AEE,0x0DAE0811BCB5C7A9,0xD0ACE6E70D6CE1E6,0xDEA3923A6B2E3298,0x91B6290CF7736D70,0x3DF94A9CCF324E7F,0xE586846F1D4E7610,0x56B5DE95A02F7EFE,0xBA4E545265BE062C,0x744102A22C8B203A,0x9FBE0D4F24A32012,0x0733A04B67805A70,0xA35BBBB8EFC0FB95,0xFE94B78F9423E963,0x407FBD7645DAC90F,0xE3B6BE7E1BD668E4,0x7672A7E923391FC9,0xB66DB38E1010202F,0x76100C33713364F6,0x1454A188CC1066D5,0x6A7DA8AFE7A053A3,0x960288E642A07B39,0xCC62C15DC78E0CBA,0x69B4B4837E8CB6C8,0x4C089E52F74B9DE5,0xCD7BFCB429822778,0x974BEF8FE7EEF55B,0xD92BDAD8E1EE38F9,0x3522521650981C3F,0xA64BDE91FD9755DF,0xBA2D15EC9C6FDC57,0x5F681F8B414E93BC,0x1F6CC7F9D817644C,0x301F125E64800E88,0xC36D3B193AA6CCF8,0xFFC6F8A1DD67F3C1,0xFBE789B3CDCF0E2F,0xA92DA702A9C516B0,0x5380E7CD619325A3,0x2068B79EFBBBD5BD,0x78CE69AD512F15C9,0x490FC360CA6AF194,0xAC10802533DAB299,0x0EA78B358B69E006,0xB8DBD64AFEEF0209,0x80C8372B05B5B874,0xBEBAD3B74257D2D2,0x4D4156AC8221D744,0xF31796F163FC9362,0x74AAAE5B93A4AC70,0x0B9EEBFEA748C862,0x29B2DEF175C37DD1,0xC60AC8179E395321,0xFFF0445E2DBF68CC,0x500853C47B335581,0xB4CA3BDC8F86754D,0x8C48BDFDEF4797B9,0x6D4CCBD9EEF8CAE7,0x85061A908CDE5A86,0x73A17F764B997E57,0x102233D6EFA388D2,0xA506413FD4067765,0x93961E53163075AF,0xF1C0101BAC065066,0x48A23404C44CFD0F,0x587CC52E71394A23,0xB38A95A5E8402FCB,0x0C8080CD390BFA54,0x1E67516DD9BDEE06,0x9A361BFDD96E4010,0xAA1B6B98EF2A2E97,0xA23FCAC73F8757B9,0x276066A6D1030B84,0x0B5AB67B9D8C494C,0xDE14FEF45EBB40C3,0xEF5AB5E9A6A119FF,0x0357F68E7FB99CFF,0xD75512602CF090D5,0x041EE5162E0C9314,0x7CC52357A7A15747,0x8CEAF110A4C9A66A,0xF04800BBDBF711DC,0xE1F6F465BDC2F390,0x38D154581A524150,0x0A3464453A6F7E89,0x1AE34182D3EDCEC3,0xA1D4336A1F1E55DE,0xBF9192A38F54E77E,0xE6DB7957C81C17A2,0x75EE44092F74A8FE,0x84B38400B23CA545,0x1FDEF5E91412035E,0x0C1B6EFFB41AEA89,0xDDFAD70167652471,0xC665084C173A9531,0x18CAC07D52749505,0xF28A616F0CFADFA4,0x98448BC3A8441232,0x7618C9E0C5CC98A5,0xF078ED4D62EB0A27,0xB6C9F3D116CF9A8A,0x76AEE59175A63973,0xDF718C87C5782ED0,0x8BF94D7E69469C8B,0xEC88D0BA873B5F4D,0x75800199BCE14CEB,0x6CE6F68DF0C23910,0x476C5A8E12D55F05,0x3B20F860A4252886,0xBBD1EB2E41C80275,0x0E852E6A78D87866,0xD8C261BBF079A63B,0xABAC0AE128FA848A,0x0D70A863580687D5,0xF12D1A3D66CC47FA,0x21B5AE0D6E79E8A9,0x7AAE6E310F6CB730,0x0B0139F1644E2424,0x54E1D9D2992DA91C,0xAC332D5B110D8C98,0xEA4922014785A7AF,0xC31E17CA81BC42E1,0x2934AE885104A98B,0x65365B533537D2B0,0x0D0485C032A74B54,0x0047423423818E1B,0x4291FB9550EAFA44,0xF84F057CF23E90CF,0xAA2AA49F3B584543,0x74952E0B6BA46151,0x0BDABEF8A5262858,0xB07BFBF8A38CCC99,0x02E7DC94BE808F42,0x0C6B5167D232A233,0x86856BA7CF034F67,0x61C3EE8ACAB18AF6,0xE0836280912A7550,0x11506E7EDF51728E,0x7C9F2E2FDEB701A1,0x8B5EE052EA74049C,0x3C1CE0FE61D8E586,0x14D06D9B37934007,0xCDB8953E098D984B,0xE0D132C686BEDD38,0x0687D8F2715124BA,0xB2AF0F08E88E1653,0x3C0B039837DEA51D,0x130DDB15573EFAA6,0xD0843E9CFF8A87A6,0x3ACD48DF0DA42126,0x9DD5625DC8218826,0xC6F869EF33240C6B,0x993AD5EDB9EBF7A9,0xDC72E09C8A689DD3,0xD110DCD6DEE1C481,0xDB4C89BAAF12784F,0xB5E0B7B56FCCE90B,0xEC9315E83BD0F5B6,0xE78A7A353AB6254A,0x96BC6A3ED77CC3FD,0xD95C7E4651342668,0xE597A546FC2BF5AA,0xF337415B638EDF6B,0x4A21B9F4F7502FED,0x423939A81A34DB17,0x10788190442D3531,0x3910903E910C977B,0x6E98227A501B93CB,0xA9FA2CC895C11714,0xE19688396A3FD790,0x5705EF18B872D81F,0x53D46A1B3869208B,0x3CBC858601D99243,0xB05B1279029D35E2,0x2D35E538CB2576DF,0x57728C6730C170BC,0x2AC2FF54FC50C6DB,0x98AD5D05DD61E36A,0x6091F4F68BB6CBC7,0xB65C300D34AA973A,0xD509D8CFDE19C160,0x261AE77BC97785E0,0x924E401605E84187,0x31FB257FFC99B056,0x6C20D1E417DA300E,0x481DADB8DF94F199,0x4CBF197F53AB6044,0xA1BB3F2511A3A1E0,0x035A56C686ABF3EE,0x2E76C2DAB80D0212,0x7776EC7B4656693F,0x5AA8CD0CB47BBCA9,0xA08167228C8DE7CD,0xD4332DD7789EA3C2,0xF4FCB962D29E768A,0x94D908B7B3974EBE,0xC367A3912032F674,0xFAFF1FF08A7C95AA,0xF5AF7CD489370EC5,0xA49E6DEDB4F2CE4F,0x2E6E51DB6124CBB6,0x82DF29EA95112E14,0xD423E60D467902E3,0xE0A7B0A017E6AD19,0x6F19E2C9E068E6B9,0x3BA694119A1029DC,0xFA974AED3B4B25AD,0xC00DE4C6979ADCCB,0xF90C3D2B96380346,0x710CDC2CEE764BA1,0x2C1D7686EF755674,0x26C747F303C7E59D,0x525C0990A1994E86,0x38C863207C638D71,0xB769751BD75541FC,0x703D98BB71653A18,0xD111BFEBBE8ED23A,0xD78C0F31D9D24241,0x0988D191FB51778C,0xC7F1CEBF914ED01C,0xC742329CCC76C21B,0x36EDDB7AA3D0F2F4,0xCF4B6865D2F3744A,0xFE3B17D553503BD0,0xA38E3EE0C1D59FE5,0x02BA4FBD9FAE2284,0x9663E5DDF1ADCB2F,0x341BC27F9ECFFE9C,0x334F2B9EB7F8CDB0,0x6346256BF3865F1D,0xA01F33BF9E7129B5,0x214B119C51130513,0xD85C77AC0F74AB53,0x9B0A95575EF086EF,0x7329960A7DE2B4FE,0x60DB00D79F1F515A,0x9F91DFD7C756CC39,0x7808EB6B8FFF70F4,0x4DCD43964EAF886D,0x079404571A91F241,0x6111C91347903F9F,0x8B44926A9526420F,0x51581136133AF8A7,0xB8CE20DFED15C116,0xEBF61C950057FD3D,0xE5B60E8A27530871,0x427689184AC7A352,0xBA7920F5A146DC93,0x2C3E55E39E5362E3,0x86194674A9760E35,0xF0B6CC4AD16B78B5,0x0E48E700FBCEA81F,0x2904EC6C2F3A7CFA,0x5EF41B369138EB14,0xFD40AFDF77F51FA3,0x023E9FE699F57995,0x3B505952BA23B99F,0xFE062589D741CB98,0x2443B5C22C7981EB,0x55EF50F94F6F4840,0xCE3761536C3356B9,0xA55103E7A7D3446E,0xAE2FE144C0EB95E0,0x9DE96AA1E4EDD730,0xC0C562A16751ACE6,0x398B6584D7621A6D,0xFF34F35CAE8EA00E,0x958A48C6D363A832,0xA3A2B51C0A78CD46,0x387FCF0CF190E81A,0x64FEAC9804D879C9,0x375CB5D39219340C,0x8CFAA7BCCB8BACE6,0x80C3A12AF9843502,0x08C4E1D63125C6C6,0xC343934A0407DBF4,0xD17541B5DD0F4071,0x8F48B69A23A1B565,0x79FE763E76A4FB5D,0x4D18B4A3A76C94A6,0x2FBC0E5FD8C5B0C5,0xF9B1E75BA09C624D,0xCDA0BB9428B35126,0x6DCE1420EACDAD72,0x653A00353E370290,0xFDCEF7CBEF228E2B,0x03F8409D4776236F,0xE898D262EC199BCB,0xAC9E1440801BF99D,0xA768A1EA68E30A8F,0x38C2E7B8C54DA058,0xE311A6DF4BA2491C,0x6C5ACE9280E884A0,0xA31BDA48D7FC7EF3,0xB4F4B4983BCEE9FD,0xFAD4B2FBC0DB8DF9,0x28F7367968B8073D,0xE06DF99D9189E874,0xD48BCF5E1F7E7D08,0xABA84DEE791EB973,0x71B46F8B25793B1D,0xA5EFB0C39DA5728A,0xE6D9AD365425180F,0xD34237E31E6A1AC0,0x916E2AEAA0800791,0xFE95972C5A4909F8,0x0A4EE7CB1629A39F,0xA073DFCB84FE9167,0x8F12D70C5D4E0B96,0x31B54C737E8D13C2,0x53B96AD9A70CEC5D,0x7F9A2360A6D6394F,0xA35BEC8BF730E494,0x5AB40AC70EEB9150,0x4BE0C1F13B2ACE93,0xC50E33A3E8E1BE11,0x498AFEC0215CDF45,0x7C266DFBA960B1D6,0x3D2E7CEA9F2DAD3D,0x72AE523B49D7E5D6,0x0139A418D53B0651,0x7E48774EF6452155,0xD8772DA60089757B,0x5B999F05299EADE3,0x298CC941EE020F3C,0xB7B955F59BD1288C,0x790C6315A1D51B7C,0xF426D682E917B64C,0xE24DBACF2A1F44A0,0x03E42AFCBB495595,0x3438B5ECA60338EB,0xF9A1492565BCDBF3,0xCAEB87776A606CB9,0x3BC11CF7880240DC,0x04D21726160583E4,0xB8280D9C0F6E3C91,0x9B7510B30F088A56,0x5B21EC22C6627C67,0xA9C23754188EA937,0x2EBC756EE4079CA1,0xA6B2878DF0A0B453,0xB973718D9BE79E1B,0x08704865BCC98F58,0x3125A0F00815D8E4,0xC22F1AF661ED651A,0x5D34E53AF16B6F19,0xAA57EE199C565418,0x8D7A41754B22150F,0xCF0A4D08AA6396FA,0xEBDE508186021960,0x6E8BBE9F356CB76E,0xEA01D2AD886E1A6C,0x4521140E9D179BAD,0x0B2A83FFF831308B,0x3D83BB897756EFA3,0x2881EBD7B4392F9F,0x5A6BF6775C305F6C,0xB2632128216A7323,0x4D8969AB36CF9A82,0x78D82C4E24287E89,0x5D1778A2084F7261,0x3B9E5A7A10F6B964,0x7BCEF5D29BEDB485,0x4B01423DD4D79AD2,0xB0AB51D5A3338D4C,0x787168F750AA39B6,0x53A824FF970FD736,0xF9A9F5F3AF2CDD56,0x5CA09861C6BA8E93,0xD0FF9E29FF3F1DC1,0x52DBA0B551DCF4B7,0xBB6065DFA70A2225,0x5059E744EBC51891,0xDD7BBF0798F515BD,0x3C5FD784C01DDA8B,0xB238AC2C99BB9651,0xFEDCD6F5A972498A,0x768C1BE3263B0958,0xF60078954557F4CD,0xA086A141794B3F9E,0x348D2A10E081CC56,0x3657C6FD1746967F,0x0DCC9EB72F0EE8C9,0xB71F835479165A73,0x4B2B44C3FF5D2A3C,0x88E4960CD158B5A4,0xCC8841BBDD2BA457,0x0CD8508FBFC856E9,0x97D90AF7A578F223,0x8BAB579396168AD0,0x468BEF937FDC7EEF,0xE94BDED7833A87C9,0xE08F86D0F0047EA3,0x386BBAC8D6A9A30F,0xE2929EB990EA29C3,0x16F99DD7C650AD13,0xABC49336E448DCCF,0x44568FF8A6DF1470,0x285983960726BBCE,0x2297597D21B877B9,0x2FADA3CD25A92300,0x7BE10D720B3DB90D,0x0533CC64562E44E5,0xCC6E98EBD7790F0A,0x4C7BC8E08DC91A09,0xD527B4252BD1F744,0x6598AF8AD023607F,0xC3C1939FD38DE8BD,0xBEA5CD99F2079630,0xEB0114E55956CE5E,0xDF265365EEE1543E,0x407A6B0841F68112,0xAF683A0D7B123478,0x438950668CE17966,0x5C440CA1D68BAC25,0xEC245932A79268F1,0x8AFBECD503CDF178,0x278D19B35512A948,0xCB722DED501A51B2,0x473904E7DEBA556D,0x1112BE77B4EA0EDF,0x5D14F701FF47A438,0xB500FE46004E18F2,0xA287C5A2F4908804,0xEE34835ACA333283,0x8869C739DC84E12D,0x7156D75A4ADEC16E,0xA02C7AD6AD197A32,0xBFC7F1EF2B4BCEBD,0xDB5C85DA52411FDE,0x9D11F369F614A19F,0xFFD21084CD015F43,0xA7CE7F8BD62012AE,0x66DB4E56F3B8682D,0xB198278F3B0F69F4,0xFB68C0DA013B3177,0x06ED7AC097CAEAF5,0x285BA6295584793C,0x8E7E509DCE486B45,0xD2EBDEDA01BF0680,0x403256C29A6B0C3A,0xF243B30937E0B9D5,0xA60691DACC8E22E0,0xF400868EE1E620EA,0xF009CA5D0AAA0C52,0xBD8FCFD687B9C55E,0x03335DA2708C389A,0x93A05EF793A8782E,0x8F6725C3ED633F28,0xAA9148F85AD551B0,0x288A9E04A992189F,0x39E883D30D00AECE,0x188FAF6FC7DC6FCE,0x058BBBA8042EF3F8,0xEE5F09EC03A23E76,0x179B34EC2A3C2C49,0x1A20C57F14B6BE40,0x000563767C26EFA6,0xB693516893D00458,0xE1DB5CE13D015C05,0x32CABBE251B20124,0x2FB2A9DEB94E94C2,0x2CE28ACD331812CA,0x994BE6794063273D,0xD59BD11F570B46CA,0x6EBFACCDBFC67A05,0x016AB9E9C583B132,0xC57F33997F746F6D,0x9225EE968A753843,0x50FABE8486D7C628,0x420BE4925E8405BD,0x1373032C5C44D801,0x9AAB284DDD995689,0x96A56D0ED975DAA3,0xC3C6D7A807AB6100,0x3EAD25CDAA61DBB1,0xF1F3BE4B78F77857,0x713E2F66C5F72D68,0xE6A35C464F3D19A3,0x23ECEA522A640FE0,0x2C212ED054EC2E16,0x5FAF5EF254B35878,0x68ED7A80FEAD7B06,0xF58BEAC373C4B290,0x41D8024CC0494997,0x3641EF6146852F83,0x294274D4E7AA698B,0x799EDC508AE58A21,0x0CA8AF0D2309B42A,0xDB40B7A17A51F0B3,0xD7DD1FDB1B5185F9,0x61C3AEB096EFAD80,0x37E9CC007FDDAC62,0x6F1F0887010530A3,0x3382847E32FEE9E9,0x92E26F704194068D,0x1CA99AD3533EEAF1,0x74FE60A440A622A7,0x5271E13D091A5F6F,0x1FE809468D2BBB47,0xEA0AEA0982E88A53,0xC3C8D8F8FD18EDA8,0x66F9D0F8195F4D0A,0x20791B420F238F87,0x415CBAF8E185A04D,0x1D5BF9074A08C212,0x75668283DB2E52D1,0x49F57012EE8A9E85,0xE2FC31006C87CAA0,0x41EB358472421328,0xDE6F8C01CC71C4B1,0xD1A8D192501AA0C3,0xCB0727C6DBB39720,0xE2CB0F29D42896C8,0x3759EBFD1C1DCD25,0x2019574F6278EAF9,0x37316DAE00D84B20,0x155EC7616A7363E5,0x17ECBF34140F3A65,0xDFA43229A6F6EEAC,0x60B4B253C44F8C9C,0xBB8A4324D1BD70E0,0x46AAFD5CAAB730CA,0x9D4D4EF74A430794,0xA082BE9545FFD327,0x5E4A1A96DC13BB35,0x4E37EC46607E4F47,0x07CE28D3387288C1,0x3238FA1C7B404861,0xFB11009B291DBEDB,0x187F65038EAD9958,0xBEFB207FFBB5F7C9,0xE939E54B8AA7C93E,0x5C6E7A742801B779,0x1C079A4067B8C326,0xD3726CCAB1CB007B,0x1E693E02910B138A,0x34D8756B48B3E08F,0xF455FA5E31FFF9F3,0xF19EBB90627184A8,0x108E03CA4F59065D,0x6C4B89D818F18FD6,0xE38A0E56CC36C2EB,0x50C46E034883B691,0x3198DD60D63EA39A,0x640361937CC8ED94,0x462B41F1E53CEC63,0x588B88BEB0D4EA7B,0x12EB21C4C93E66D3,0xFBCF54028B9B8961,0x7942822864DFBBE6,0x4D3A57A163F06FC1,0x7F1C55B3CF7090A9,0xCF50FBAB99970E4F,0xA546CAA3483E6E98,0xFC094B55A01C1EF1,0x7AF631762CD7CD7C,0xC3C8C6A2F5A59B63,0x2E750249D6A9DBCD,0x4D34436C8AC01A72,0xB1980060EE83339E,0x96D6A1D56237A203,0xF3AAAB4826833D1F,0x41B99FCA8F6BD17D,0xE14640DD90C9D54C,0xCC16FFAFA4307C3A,0x2DEEDB3A7CC6F0D7,0xA918853B18B74748,0x694794AF749D44C3,0xE6F4B7A4513D79C9,0x28D7C6429BEC7D34,0x204FC59D808FB744,0x056A5128E71E2D35,0x5927ADF7307D11FF,0xBF0B688E6E36F168,0x3114DE4257A9CF0C,0xFB8579297F592E52,0x32C98584FDE293A2,0x15CB7D507F7667AC,0xFCD228B44292BF1C,0xF5E5786A4EF2A39B,0x1F136257AE0B55FD,0xF91AF89D5F70F12F,0xA71AE5C74B882FD3,0x966850E51F5AD965,0xAB8EA9417E238DF2,0xDEDA51FF80C037F3,0x5409AEC70FE86EED,0x43AF9917F8FE89CF,0xFEEE11C810D38E64,0xE60F2D8B6377DA9E,0x4DE4E8B7E5995702,0x23923979908B0002,0x3D6161B9DCD101AF,0xD8278AADEBDD916F,0x23FCC98C486371C0,0xBB2A3F1F88FA6EDE,0x4A0DF93CCF6C06CB,0x2BD0880741CC09BD,0x27D14D8C41C90450,0xA32110C5F87A16CD,0x6CD2C67E26FC5F96,0x9ABE4BB0B60B5F12,0x4EF93DCEAA11A6BE,0x6ACB2AA321C4F134,0x33046CCC97D9F137,0x2ABC19A3C37238F7,0x5F611B0DC3EB1934,0x0AA19C6C0D543FD9,0x9749422CAAFBBDF0,0x1C5A399E7EE05DB7,0x72171C2099303209,0x7EED382A542E3226,0x4B9BE1CD3FBA32CC,0x9910BD43F1245403,0x1F21DFD51EFB5FC7,0xBB7360C6677908A2,0x504189CFC609D5BB,0x42EA88FF91FCB840,0x67C6EFDBB8607D70,0x13DF1F90142227AD,0x4418EDCA15F041FF,0x6A4782B593B73FD3,0x40B603B8B7BB4FC0,0x17B2A422D32F3616,0x4188C5D7FFDF9CC1,0x0AE5636A5FD3F485,0xC1F44A25A218DDC3,0x0AA1322D8CC57A66,0x24EB7D15542320F0,0x0910984B8D79B3B2,0xC69205E52AF28522,0x4CEFDDD1E4CE4914,0xDBD24269B742FB99,0x5DFA10F51C0A710A,0xF7FAD0987CDA6A24,0x3D52CF06582B7BD7,0x5997A188F5B79BCF,0x4C5099A362CE8458,0x9BF94AC467B74906,0x7E46D31094D787C4,0xA167CAFBA1CD9349,0xD51A7C2DC765BB7C,0xF9EEC0724F17BBA9,0x4FED42F156DE787D,0x54656B3592CAC6BA,0x38A690F9EE667562,0xA64443B729B42E79,0x9666CDE477DD82DC,0x8EDE5D30781BC4D7,0xE88DBC19C4C75549,0x43B1BD37B3B4A35C,0x80D0536FE9326BD0,0x6BE674458236A964,0x40BA50CBBFB80336,0xC1D8C9897E8E7FD2,0x1B6FB47A8A5FC634,0x38DAB2F5026199A6,0x5478B6A97F8663F0,0xCCB2A2244FE4F2D9,0x34A7450B2D4C5216,0xA807A912522184AB,0x5A52D3EB39561663,0x954956556A0FA571,0xED15E0E61CABFC4E,0xB71138D986104D0E,0x398EB44754B2B349,0xC3DB296A90F37101,0x425888B56E176DF7,0x4254708446EF33C5,0x2336C2BA42152E7B,0xFA2D3471A401E332,0x7DD8AF43524DAB6A,0x36062554B2D98C1B,0x46DB12A1CDA7886A,0x512DAD6C5D5E7C8F,0xE67D1ADF6873D379,0xE7FCCE188E1E813D,0x22006365559ED923,0x53054CFFF7243745,0xF6F86B534DD91EB4,0xCBD927D028031C7B,0xD5F28AA1B8C98B4F,0x701C22ADCBA1E5B1,0x2FF42A1B3B25D162,0x5333A98D9030A63A,0x3532074FE3BA35EA,0xB4041CBF511F23D9,0x4D1F6143E30121B3,0x372BDB5B365E7131,0x13B055C40F8D9241,0x6998A1AE0DD613F3,0xC7AC3199E9944920,0xE028D88BA0D57CF2,0xD630D887392EBEF4,0xC34BE2BFF244DC9E,0xB9D51177B10651CB,0xA8FE85B2952D5C7B,0xCF234C204079AC67,0x184A6F4D42DE81C4,0x40225799504C1014,0x36A6DD287A11B104,0xD3FB2FE0506B94D8,0x0574C5B316C09A6B,0xA8AC36FDEF318A36,0xBFEC75195252AECA,0x3424FD51252012F1,0xAEAE92785937E54B,0x7A35DDE055E1F5FA,0xD270FC161443F364,0xAB5D6DF94E977F14,0x40F363F393806D67,0x17A0A2C73E155998,0x841B010632981D92,0xA87691539A27B40C,0x38F5676028956030,0xAAF19E717DF71B20,0x74452B545E701938,0xA8AE000A30C10C37,0x40276E447B1007C9,0x3D5324E21748DD07,0xE3344B79286CAB09,0xDB5F8C8813D7EEF0,0x71E02B6A7DC3BDEF,0x68C79C8DD9AC7270,0x32FDCE510E2F217A,0x0E753012FD2DF9C2,0x590CDC8A827FB2C1,0xBA7AA9B7212C2E6C,0x040DEE7D5A6514A3,0xBEF42A86162982FB,0xC4CB8FE00EF0DE31,0x27CDD7B8EB54B3B9,0xEF85E9ECF23DC48C,0xF9F8947A353BD9BE,0x32E36FAA09057F10,0x5E5C86DBE405D21D,0x53844A7B7B39A4A3,0xCC703B0330395D84,0x36C1403F675B49FB,0x301D6FB452B89F09,0xF7646818A1EDC415,0x5E07785E01C2DBCC,0x50859ADECD73731B,0x423D8BD8BF6C0A63,0x53607AD093997E42,0xDA750FF39E279CF0,0xBCE905F7A2A557BB,0x3BC1B473F5882806,0xC25BDDAF9E5AB6D7,0xBD46E4EFB5B0554D,0x3C3FCC887E88EEF2,0x003D6D0CCB386955,0x172546D0CDA74DA7,0xCD42EC696ACB554D,0x50D94EAFE1C92DAD,0x23264B7599540551,0xDFB83B78015CD470,0xD0EDBC31767823F2,0x84795B79649B51F2,0xCBC23512D9E46C09,0xBE57C14FCC01FBAE,0x93E4555DD809CDFC,0x0960A1A817E64F32,0xD51AD5A23D3C75E0,0x6F36D5DE00C61F83,0x8A89212D0F4B673E,0xB73D8C2638FCF797,0x699E8FE800F74F7C,0x5AB4BAE3991F9435,0x6FB5F6CFB8C6BF7D,0x368D8D7753AA0EBE,0x0BC720CFE34F37E1,0x58F0DE0093D73A62}; +#endif diff --git a/shelter/lib/include/kernel/tests/test_queues.h b/shelter/lib/include/kernel/tests/test_queues.h new file mode 100644 index 0000000..b0cdd4f --- /dev/null +++ b/shelter/lib/include/kernel/tests/test_queues.h @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_TEST_QUEUES_H +#define SH_LIB_TEST_QUEUES_H +#include "std/stdlib.h" +#include "cpu/tsc.h" +// Test and benchmark queues from standard library +SH_STATUS sh_test_benchmark_queues(); +#endif diff --git a/shelter/lib/include/kernel/tests/test_utils.h b/shelter/lib/include/kernel/tests/test_utils.h index e5a8ef9..54b459f 100644 --- a/shelter/lib/include/kernel/tests/test_utils.h +++ b/shelter/lib/include/kernel/tests/test_utils.h @@ -5,7 +5,7 @@ #include "std/status.h" #include "cpu/tsc.h" // Compute and print time stats based on provided list of TSC values. -SH_STATUS sh_test_compute_print_stats(char* benchname,sh_tsc_TSC_VALUE *tsc_value_array,sh_uint64 array_size); +SH_STATUS sh_test_compute_print_stats(char* benchname,sh_tsc_TSC_VALUE *tsc_value_array,sh_uint64 array_size,sh_bool use_std_print); // Return pointer to TSC values buffer sh_tsc_TSC_VALUE* sh_test_get_tsc_values_buffer_ptr(); // Load the number of iterations for benchmarks. diff --git a/shelter/lib/include/memory/memory.h b/shelter/lib/include/memory/memory.h new file mode 100644 index 0000000..27829c7 --- /dev/null +++ b/shelter/lib/include/memory/memory.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_MEMORY_H +#define SH_LIB_MEMORY_H +#include "std/type.h" +#include "std/status.h" +#include "kernel/conf.h" +#include "memory/page.h" +#include "memory/slab.h" +#include "memory/heap.h" +// Memory subsystem services structure +typedef struct { + sh_page_PAGE_TABLE_POOL kernel_ptp; + sh_slab_reg_phys_SLAB_ALLOCATOR slab_reg_phys; + sh_slab_reg_virt_SLAB_ALLOCATOR slab_reg_virt; + struct sh_slab_radix_node_SLAB_ALLOCATOR slab_radix_node; + sh_pez_PHYSICAL_PLANE physical_plane; + sh_pez_VIRTUAL_PLANE virtual_plane_kernel_heap; + sh_heap_KERNEL_HEAP kernel_heap; +} sh_memory_MEMORY_SERVICES; +// Initialize memory subsystem +SH_STATUS sh_memory_init_subsystem(sh_conf_BOOT_CONFIG *boot_config,sh_memory_MEMORY_SERVICES *services); +// Identity map a physical memory area +SH_STATUS sh_memory_identity_map(sh_page_PHYSICAL_ADDRESS phys_start,sh_uint64 page_count,sh_uint64 flags); +// Parse a memory DevS query +SH_STATUS sh_memory_devs_query(char *sub_path,sh_devs_RESULT *result); +#endif diff --git a/shelter/lib/include/memory/page.h b/shelter/lib/include/memory/page.h index 23b8b6a..4ece20c 100644 --- a/shelter/lib/include/memory/page.h +++ b/shelter/lib/include/memory/page.h @@ -156,4 +156,6 @@ SH_STATUS sh_page_analyse_memory_map(sh_page_PAGE_TABLE_POOL *ptp); sh_page_VIRTUAL_ADDRESS sh_page_get_physical_bitmap_ptr(); // Get physical memory statistics SH_STATUS sh_page_get_memory_stats(sh_page_MEM_STATS *mem_stats); +// Return total installed memory in bytes +sh_uint64 sh_page_get_installed_memory_bytes(); #endif diff --git a/shelter/lib/include/memory/ring.h b/shelter/lib/include/memory/ring.h index dc8115f..a862f6c 100644 --- a/shelter/lib/include/memory/ring.h +++ b/shelter/lib/include/memory/ring.h @@ -15,4 +15,6 @@ typedef struct { SH_STATUS sh_ring_write_byte(sh_ring_RING_BUFFER_HEADER *ring_buffer,sh_uint8 byte); // Write a null terminated string into the provided ring buffer SH_STATUS sh_ring_write_string(sh_ring_RING_BUFFER_HEADER *ring_buffer,char *string); +// Read bytes_count from the provided ring buffer, and put it into output. Return SH_STATUS_TOO_MUCH_DATA if bytes_count>buf.buffer_size_bytes, setting the entire buffer to 0x00 +SH_STATUS sh_ring_read_bytes(sh_ring_RING_BUFFER_HEADER *ring_buffer,sh_uint32 bytes_count,void *output); #endif diff --git a/shelter/lib/include/memory/vmem_layout.h b/shelter/lib/include/memory/vmem_layout.h index 98e38bf..87968fb 100644 --- a/shelter/lib/include/memory/vmem_layout.h +++ b/shelter/lib/include/memory/vmem_layout.h @@ -79,7 +79,7 @@ #define SH_VMEM_LAYOUT_SLAB_REG_VIRT_VA 0xFFFFFF800C600000ULL // The total size for the slabs for virtual regions objects #define SH_VMEM_LAYOUT_SLAB_REG_VIRT_SIZE_BYTES (1ULL<<29)*12ULL -// The alignement for SH_VMEM_LAYOUT_SLAB_RADIX_NODE_VA +// The alignment for SH_VMEM_LAYOUT_SLAB_RADIX_NODE_VA #define SH_VMEM_LAYOUT_PBA_RADIX_NODE_BLOCK_ALIGN (32ULL*4096ULL) // The base for the PBA for the slabs for radix nodes #define SH_VMEM_LAYOUT_SLAB_RADIX_NODE_VA ((SH_VMEM_LAYOUT_SLAB_REG_VIRT_VA+SH_VMEM_LAYOUT_SLAB_REG_VIRT_SIZE_BYTES+SH_VMEM_LAYOUT_PBA_RADIX_NODE_BLOCK_ALIGN)/SH_VMEM_LAYOUT_PBA_RADIX_NODE_BLOCK_ALIGN)*SH_VMEM_LAYOUT_PBA_RADIX_NODE_BLOCK_ALIGN diff --git a/shelter/lib/include/std/print.h b/shelter/lib/include/std/print.h new file mode 100644 index 0000000..243ef6f --- /dev/null +++ b/shelter/lib/include/std/print.h @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_PRINT_H +#define SH_LIB_PRINT_H +#include "std/status.h" +#include "std/type.h" +#include "kernel/log.h" +#include "kernel/conf.h" +#include "cpu/ap.h" +#define SH_DEBUG SH_LOG_DEBUG +#define SH_LOG SH_LOG_LOG +#define SH_WARNING SH_LOG_WARNING +#define SH_ERROR SH_LOG_ERROR +#define SH_CRITICAL SH_LOG_CRITICAL +#define SH_FATAL SH_LOG_FATAL +#define SH_TEST SH_LOG_TEST +#define SH_FAULT SH_LOG_FAULT +// Setup rings buffer for APs +SH_STATUS sh_print_setup_ring_buffers_per_ap(sh_conf_BOOT_CONFIG *boot_config); +// Print string +SH_STATUS sh_print(sh_log_OUTPUT_TYPE output_type,char* text); +// Print string, format it before hand +SH_STATUS sh_printf(sh_log_OUTPUT_TYPE output_type,char* format,...); +// Priority print string, reserved to IRQ handler +SH_STATUS sh_iprint(sh_log_OUTPUT_TYPE output_type,char* text); +// Priority print string, reserved to IRQ handler, format it before hand +SH_STATUS sh_iprintf(sh_log_OUTPUT_TYPE output_type,char* text,...); +// Format a string and put it into the provided buffer +SH_STATUS sh_sprintf(char* output_string,sh_uint64 output_len,char* format,...); +#endif diff --git a/shelter/lib/include/std/queue.h b/shelter/lib/include/std/queue.h new file mode 100644 index 0000000..6ca7a5f --- /dev/null +++ b/shelter/lib/include/std/queue.h @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_QUEUE_H +#define SH_LIB_QUEUE_H +#include "std/type.h" +#include "std/status.h" +#include "devs/input/event.h" +// Keyboard events queue structure +typedef struct { + sh_kbd_EVENT *buffer; + sh_uint32 capacity; + sh_uint32 write_index; +} sh_queue_KBD_EVENT; +// Initialize an event queue +SH_STATUS sh_queue_event_init(sh_queue_KBD_EVENT *q,sh_uint32 capacity); +// Push a keyboard event to the provided queue +SH_STATUS sh_queue_event_push(sh_queue_KBD_EVENT *q,sh_kbd_EVENT ev); +// Destroy the provided keyboard event queue +SH_STATUS sh_queue_event_destroy(sh_queue_KBD_EVENT *q); +#endif diff --git a/shelter/lib/include/std/smp.h b/shelter/lib/include/std/smp.h new file mode 100644 index 0000000..2642954 --- /dev/null +++ b/shelter/lib/include/std/smp.h @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_SMP_H +#define SH_LIB_SMP_H +#include "std/type.h" +#include "std/status.h" +#include "cpu/ap.h" +#include "cpu/serial.h" +#include "cpu/asm.h" +// Write GS base register +inline void sh_smp_write_gs_base(sh_uint64 value) { + sh_uint32 low=(sh_uint32)(value); + sh_uint32 high=(sh_uint32)(value>>32); + __asm__ volatile ("wrmsr"::"c"(0xC0000101),"a"(low),"d"(high)); +} +// Return CPU struct of this CPU +inline sh_ap_CPU_STRUCT *sh_smp_gs_base() { + sh_uint32 low,high; + __asm__ volatile ("rdmsr":"=a"(low),"=d"(high):"c"(0xC0000101)); + return (sh_ap_CPU_STRUCT*)(((sh_uint64)high<<32)|low); +} +// Lock structure, unlocked lock have lapic_id to SH_UINT32_MAX +typedef struct { + volatile sh_uint32 spinlock; + sh_uint32 lapic_id; +} sh_SPIN_LOCK; +// Create an unlocked lock, intended for creation of global variables. +#define SH_LOCK() {.spinlock=0,.lapic_id=SH_UINT32_MAX} +// Create an unlocked lock, intended for creation of local variables +#define SH_LOCK_LOCAL() ((sh_SPIN_LOCK){.spinlock=0,.lapic_id=SH_UINT32_MAX}) +// Lock a spinlock +inline void sh_spin_lock(sh_SPIN_LOCK *lock) { + while (__atomic_test_and_set(&lock->spinlock,__ATOMIC_ACQUIRE)) { + while (lock->spinlock) { + __asm__ volatile ("pause"); + } + } + if (sh_smp_gs_base()==SH_NULLPTR) { + sh_serial_send_byte('!'); + while (SH_TRUE) {} + } + lock->lapic_id=sh_smp_gs_base()->lapic_id; +} +// Unlock a spinlock +inline void sh_spin_unlock(sh_SPIN_LOCK *lock) { + lock->lapic_id=SH_UINT32_MAX; + __atomic_clear(&lock->spinlock,__ATOMIC_RELEASE); +} +// Try to lock a spinlock, doesn't wait for it to be unlocked, return SH_TRUE if lock is now owned by us +inline sh_bool sh_spin_trylock(sh_SPIN_LOCK *lock) { + if (__atomic_test_and_set(&lock->spinlock,__ATOMIC_ACQUIRE)) return SH_FALSE; + lock->lapic_id=sh_smp_gs_base()->lapic_id; + return SH_TRUE; +} +// Return which CPU is locking the lock +inline sh_uint32 sh_spin_wholock(sh_SPIN_LOCK *lock) { + return lock->lapic_id; +} +// Set CPU count (aka max_cpu_id+1) +void sh_smp_set_cpu_count(sh_int16 cpu_count); +// Return CPU count, return -1 if this value isn't initialized +sh_int16 sh_smp_get_cpu_count(); +// Memory barrier +inline void sh_mb() { + sh_asm_mfence(); +} +// Read memory barrier +inline void sh_rmb() { + sh_asm_lfence(); +} +// Write memory barrier +inline void sh_wmb() { + sh_asm_sfence(); +} +#endif diff --git a/shelter/lib/include/std/status.h b/shelter/lib/include/std/status.h index 3c4f4bd..0037457 100644 --- a/shelter/lib/include/std/status.h +++ b/shelter/lib/include/std/status.h @@ -36,6 +36,17 @@ typedef sh_int64 SH_STATUS; #define SH_STATUS_PAGE_ALREADY_FREE 25LL #define SH_STATUS_TOO_MUCH_DATA 26LL #define SH_STATUS_HEAP_NOT_INITIALIZED 27LL +#define SH_STATUS_MEMORY_SUBSYSTEM_NOT_INITIALIZED 28LL +#define SH_STATUS_INVALID_CHECKSUM 29LL +#define SH_STATUS_BAD_SIZE 30LL +#define SH_STATUS_INVALID_STATE 31LL +#define SH_STATUS_DEVS_NOT_INITIALIZED 32LL +#define SH_STATUS_UNAVAILABLE 33LL +#define SH_STATUS_ALREADY_INITIALIZED 34LL +#define SH_STATUS_AP_NO_LAPIC 35LL +#define SH_STATUS_ISO_UNKNOW_BUS 36LL +#define SH_STATUS_INVALID_HANDLE 37LL +#define SH_STATUS_DEVICE_NOT_PRESENT 38LL // Return SH_TRUE if provided status is an error static inline sh_bool sh_status_error(SH_STATUS s) { return s>=SH_STATUS_INVALID_PARAMETER; diff --git a/shelter/lib/include/std/stdlib.h b/shelter/lib/include/std/stdlib.h index 7add4a2..b4e741a 100644 --- a/shelter/lib/include/std/stdlib.h +++ b/shelter/lib/include/std/stdlib.h @@ -1,7 +1,11 @@ // SPDX-License-Identifier: MPL-2.0 // This header is just here to include all standard header -// If you are looking for printing functions, take a look at kernel/log.h +// If you are looking for non-thread safe/more direct printing functions, take a look at kernel/log.h #include "std/mem.h" #include "std/malloc.h" -#include "std/status.h" +#include "std/print.h" +#include "std/smp.h" #include "std/type.h" +#include "std/status.h" +#include "std/string.h" +#include "std/queue.h" diff --git a/shelter/lib/include/std/string.h b/shelter/lib/include/std/string.h new file mode 100644 index 0000000..122a0b9 --- /dev/null +++ b/shelter/lib/include/std/string.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: MPL-2.0 +#ifndef SH_LIB_STRING_H +#define SH_LIB_STRING_H +#include "std/type.h" +// Return the length of a null terminated string +sh_uint64 sh_string_len(char *str); +// Compare two null terminated string, both strings must not exceed the provided length. Return SH_TRUE if both strings are equals on the provided length +sh_bool sh_string_compare(char *str1,char* str2,sh_uint64 length); +// Return the index of the first occurence of the provided character into the string, return SH_UINT64_MAX if not found or error +sh_uint64 sh_string_find_char(char *str,char character); +// Return the index of the start of the first occurence of the provided substring into the string, return SH_UINT64_MAX if not found or error +sh_uint64 sh_string_find(char *str,char *substr); +// Copy a substring from a string to another string, and return the pointer to the new string +char *sh_string_substring(char *source_str,sh_uint64 start_index,sh_uint64 length,char *output); +// Convert a string to a sh_uint64 +sh_uint64 sh_string_to_uint64(char *str); +#endif diff --git a/shelter/lib/src/cpu/ap.c b/shelter/lib/src/cpu/ap.c new file mode 100644 index 0000000..d5da918 --- /dev/null +++ b/shelter/lib/src/cpu/ap.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "cpu/ap.h" +#include "devs/apic/lapic.h" +#include "devs/input/kbd.h" +#include "memory/memory.h" +#include "kernel/log.h" +#include "std/stdlib.h" +sh_ap_AP_BOOTSTRAP *ap_bootstrap_struct=(sh_ap_AP_BOOTSTRAP*)SH_AP_BOOTSTRAP_PA; +sh_uint8 *is_ap_started=SH_NULLPTR; +static sh_ap_CPU_STRUCT bsp_cpu_struct; +static sh_ap_PER_CPU bsp_per_cpu; +SH_STATUS sh_ap_load_gdt_32() { + if (sh_page_is_allocated((sh_uint8*)sh_page_get_physical_bitmap_ptr(),SH_AP_GDT_32_PA)) return SH_STATUS_OUT_OF_MEMORY; + SH_STATUS status=sh_memory_identity_map(SH_AP_GDT_32_PA,1,SH_PAGE_RW | SH_PAGE_PRESENT | SH_PAGE_NX); + if (sh_status_error(status)) return status; + sh_gdt_GDT_32 *gdt_32=(sh_gdt_GDT_32*)(sh_uint8*)SH_AP_GDT_32_PA; + status=sh_gdt_fill_gdt_32(gdt_32); + if (sh_status_error(status)) return status; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_ap_prepare_for_smp_launch(sh_lapic_DEVICE **lapic_dev_array,sh_uint64 max_lapic_id,sh_uint64 expected_lapic_found,sh_conf_BOOT_CONFIG *boot_config,sh_idt_IDT *idt) { + if (lapic_dev_array==SH_NULLPTR || expected_lapic_found==0 || max_lapic_id>255) return SH_STATUS_INVALID_PARAMETER; + SH_STATUS status=sh_memory_identity_map(SH_AP_BOOTSTRAP_PA,1,SH_PAGE_PRESENT | SH_PAGE_RW | SH_PAGE_NX); + if (sh_status_error(status)) return status; + sh_ap_AP_BOOTSTRAP *ap_bootstrap=(sh_ap_AP_BOOTSTRAP*)(sh_uint8*)SH_AP_BOOTSTRAP_PA; + ap_bootstrap->c_entry_point_va=(sh_uint64)&sh_ap_entry_point; + ap_bootstrap->page_table_pa=boot_config->page_table_pool_pa; + sh_int16 current_lapic_id=sh_lapic_get_current_core(); + if (current_lapic_id<0) return SH_STATUS_INVALID_STATE; + sh_lapic_DEVICE *lapic_device_default=SH_NULLPTR; + sh_uint64 lapic_found=0; + for (sh_iter64 i=0;ilapic_base_pa=(sh_uint64)(sh_uint8*)lapic_device_default->base; + sh_uint8 *cpu_struct_base_ptr=sh_malloc(sizeof(sh_ap_CPU_STRUCT)*(max_lapic_id+1)); + if (!cpu_struct_base_ptr) return SH_STATUS_ERROR_NULLPTR_RETURNED; + sh_ap_CPU_STRUCT *cpu_struct_base=(sh_ap_CPU_STRUCT*)cpu_struct_base_ptr; + ap_bootstrap->cpu_struct_base_area=(sh_uint64)cpu_struct_base_ptr; + sh_uint8 *tss_array_ptr=sh_malloc(sizeof(sh_tss_TSS)*(lapic_found-1)); + sh_tss_TSS *tss_array=(sh_tss_TSS*)tss_array_ptr; + sh_uint64 cpu_count=0; + sh_uint64 cpu_index=1; + for (sh_iter64 i=0;iapic_id==current_lapic_id) continue; + sh_uint8 *c_entry_point_stack=sh_malloc(64*SH_PAGE_SIZE); + if (!c_entry_point_stack) return SH_STATUS_ERROR_NULLPTR_RETURNED; + cpu_struct_base[i].c_entry_point_stack_top_va=(sh_uint64)c_entry_point_stack+64*SH_PAGE_SIZE; + cpu_struct_base[i].lapic_id=lapic_dev->apic_id; + status=sh_tss_fill_tss(&tss_array[cpu_count]); + if (sh_status_error(status)) return status; + cpu_struct_base[i].tss_selector=(sh_uint16)(0x28+cpu_count*sizeof(sh_gdt_GDT_ENTRY_128)); + cpu_struct_base[i].per_cpu=(sh_ap_PER_CPU*)sh_malloc(sizeof(sh_ap_PER_CPU)); + if (!cpu_struct_base[i].per_cpu) return SH_STATUS_ERROR_NULLPTR_RETURNED; + cpu_struct_base[i].per_cpu->cpu_id=cpu_index; + cpu_struct_base[i].per_cpu->bytes_outputed=0; + cpu_struct_base[i].per_cpu->timer_state=SH_FALSE; + cpu_struct_base[i].per_cpu->temp_buffer=sh_malloc(256); + if (!cpu_struct_base[i].per_cpu->temp_buffer) return SH_STATUS_ERROR_NULLPTR_RETURNED; + cpu_struct_base[i].per_cpu->temp_buffer_size=256; + cpu_count++; + cpu_index++; + } + sh_uint8 *global_gdt_ptr=sh_malloc(sizeof(sh_gdt_GDT_AP)); + sh_gdt_GDT_AP *global_gdt=(sh_gdt_GDT_AP*)global_gdt_ptr; + status=sh_gdt_fill_gdt_ap(tss_array,cpu_count,global_gdt); + if (sh_status_error(status)) return status; + ap_bootstrap->shared_gdt_64_va=(sh_uint64)global_gdt; + ap_bootstrap->gdt_64_gdtr=sh_gdt_make_gdtr_ap(global_gdt); + ap_bootstrap->idt=idt; + sh_smp_set_cpu_count((sh_int16)cpu_index); + is_ap_started=sh_malloc(cpu_index); + if (!is_ap_started) return SH_STATUS_ERROR_NULLPTR_RETURNED; + sh_mem_set_8(is_ap_started,SH_AP_STATE_PENDING,cpu_index); + return SH_STATUS_SUCCESS; +} +void sh_ap_entry_point() { + sh_lapic_DEVICE *lapic_dev=sh_lapic_get_dev_apic_id(sh_smp_gs_base()->lapic_id); + if (!lapic_dev) { + sh_print(SH_FATAL,"Couldn't obtain LAPIC of this AP."); + is_ap_started[sh_smp_gs_base()->per_cpu->cpu_id]=SH_AP_STATE_NO_LAPIC; + while (SH_TRUE) {}; + } + SH_STATUS status=sh_lapic_init_dev(0xFF,lapic_dev); + if (sh_status_error(status)) { + sh_print(SH_FATAL,"Couldn't initialize LAPIC."); + is_ap_started[sh_smp_gs_base()->per_cpu->cpu_id]=SH_AP_STATE_NO_LAPIC; + while (SH_TRUE) {}; + } + sh_idt_load_idtr(ap_bootstrap_struct->idt); + sh_asm_sti(); + sh_printf(SH_LOG,"Thread with lapic_id=%4u and cpu_id=%8u successfully reached C entry point.\n",sh_smp_gs_base()->lapic_id,sh_smp_gs_base()->per_cpu->cpu_id); + sh_mb(); + is_ap_started[sh_smp_gs_base()->per_cpu->cpu_id]=SH_AP_STATE_OK; + sh_mb(); + while (SH_TRUE) {}; +} +SH_STATUS sh_ap_start_ap_boot_procedure(sh_conf_BOOT_CONFIG *boot_config) { + SH_STATUS status=sh_memory_identity_map(SH_AP_AP_TRAMPOLINE,1,SH_PAGE_RW | SH_PAGE_PRESENT); + if (sh_status_error(status)) return status; + sh_mem_copy((sh_uint8*)SH_AP_AP_TRAMPOLINE,(sh_uint8*)SH_AP_TRAMPOLINE_PAYLOAD,4096); + sh_lapic_DEVICE *lapic_dev=sh_lapic_get_dev_apic_id((sh_uint64)sh_lapic_get_current_core()); + if (lapic_dev==SH_NULLPTR) return SH_STATUS_ERROR_NULLPTR_RETURNED; + bsp_cpu_struct.c_entry_point_stack_top_va=0; + bsp_cpu_struct.lapic_id=(sh_uint32)sh_lapic_get_current_core(); + bsp_cpu_struct.tss_selector=0; + bsp_per_cpu.cpu_id=0; + bsp_per_cpu.bytes_outputed=0; + bsp_per_cpu.timer_state=SH_FALSE; + bsp_per_cpu.temp_buffer=sh_malloc(256); + if (!bsp_per_cpu.temp_buffer) return SH_STATUS_ERROR_NULLPTR_RETURNED; + bsp_per_cpu.temp_buffer_size=256; + bsp_cpu_struct.per_cpu=(&bsp_per_cpu); + sh_smp_write_gs_base((sh_uint64)&bsp_cpu_struct); + is_ap_started[sh_smp_gs_base()->per_cpu->cpu_id]=SH_AP_STATE_OK; + sh_log_debug("Trying sending INIT IPI...",SH_LOG_SOURCE_SMP); + status=sh_lapic_send_ipi(lapic_dev,SH_LAPIC_IPI_TYPE_INIT,SH_LAPIC_IPI_DESTINATION_ALL_EXCLUDING_SELF,SH_LAPIC_IPI_NO_DESTINATION,0); + if (sh_status_error(status)) return status; + sh_log_debug("Sent INIT IPI. Waiting 10 ms.",SH_LOG_SOURCE_SMP); + status=sh_lapic_timer_one_shot_us(lapic_dev,10000); + if (sh_status_error(status)) return status; + sh_log_debug("Trying sending first SIPI...",SH_LOG_SOURCE_SMP); + status=sh_print_setup_ring_buffers_per_ap(boot_config); + if (sh_status_error(status)) return status; + status=sh_lapic_send_ipi(lapic_dev,SH_LAPIC_IPI_TYPE_STARTUP,SH_LAPIC_IPI_DESTINATION_ALL_EXCLUDING_SELF,SH_LAPIC_IPI_NO_DESTINATION,SH_AP_AP_TRAMPOLINE); + if (sh_status_error(status)) return status; + sh_log_disable_global_logging_ring(); + sh_print(SH_DEBUG,"Sent first SIPI.\n"); + while (SH_TRUE) { + sh_mb(); + sh_int16 cpu_good=0; + for (sh_int16 i=0;i=8) sh_asm_outb(SH_PIC2_CMD,0x20); + sh_asm_outb(SH_PIC1_CMD,0x20); +} diff --git a/shelter/lib/src/cpu/pit.c b/shelter/lib/src/cpu/pit.c new file mode 100644 index 0000000..f9f08ec --- /dev/null +++ b/shelter/lib/src/cpu/pit.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "cpu/pit.h" +#include "cpu/asm.h" +void sh_pit_set_frequency(sh_uint64 hz) { + sh_uint16 divisor=(sh_uint16)((sh_uint64)1193182/hz); + sh_asm_outb(0x43,0x36); + sh_asm_outb(0x40,(sh_uint8)(divisor&0xFF)); + sh_asm_outb(0x40,(sh_uint8)(divisor>>8)); +} diff --git a/shelter/lib/src/cpu/tsc.c b/shelter/lib/src/cpu/tsc.c index f8aa230..ef2ea95 100644 --- a/shelter/lib/src/cpu/tsc.c +++ b/shelter/lib/src/cpu/tsc.c @@ -1,6 +1,12 @@ // SPDX-License-Identifier: MPL-2.0 #include "cpu/tsc.h" +#include "cpu/pit.h" +#include "cpu/pic.h" +#include "irq/irq.h" +#include "kernel/log.h" sh_tsc_TSC_VALUE kernel_start_tsc=0; +sh_uint64 internal_cpu_freq=0; +sh_bool is_cpu_freq_provided=SH_FALSE; SH_STATUS sh_tsc_init_tsc() { kernel_start_tsc=sh_tsc_read_tsc(); return SH_STATUS_SUCCESS; @@ -11,3 +17,82 @@ sh_tsc_TSC_VALUE sh_tsc_get_kernel_init_tsc() { sh_tsc_TSC_VALUE sh_tsc_get_kernel_current_tsc() { return sh_tsc_read_tsc()-kernel_start_tsc; } +sh_uint64 sh_tsc_estimate_cpu_freq() { + sh_pic_remap(); + sh_pic_mask(0); + sh_asm_sti(); + sh_pit_set_frequency(1000); + sh_uint64 total_tsc=0; + for (sh_uint64 i=0;i<16;i++) { + sh_irq_start_tsc(); + sh_pic_unmask(0); + while (sh_irq_get_tsc_delta()==0) { + __asm__ volatile("hlt"); + } + sh_pic_mask(0); + total_tsc+=sh_irq_get_tsc_delta(); + sh_log_fdebug(SH_LOG_SOURCE_MAIN,"CPU Frequence #%8u: %8u hz`\n",i+1,sh_irq_get_tsc_delta()*1000); + } + return (total_tsc*1000)/16; +} +void sh_tsc_load_cpu_freq(sh_uint64 cpu_freq) { + internal_cpu_freq=cpu_freq; +} +sh_bool sh_tsc_has_hypervisor() { + sh_uint32 eax,ebx,ecx,edx; + sh_asm_cpuid(1,0,&eax,&ebx,&ecx,&edx); + return (sh_bool)((ecx>>31)&1); +} +sh_bool sh_tsc_is_tsc_constant() { + sh_uint32 eax,ebx,ecx,edx; + sh_asm_cpuid(0x80000000,0,&eax,&ebx,&ecx,&edx); + if (eax<0x80000007) return SH_FALSE; + sh_asm_cpuid(0x80000007,0,&eax,&ebx,&ecx,&edx); + sh_uint32 constant; + constant=(edx>>8)&1; + return (sh_bool)constant; +} +SH_STATUS sh_tsc_get_cpu_freq_cpuid(sh_uint64 *freq) { + sh_uint32 eax,ebx,ecx,edx; + sh_asm_cpuid(0x15,0,&eax,&ebx,&ecx,&edx); + if (eax==0 || ebx==0) return SH_STATUS_UNAVAILABLE; + if (ecx!=0) { + *freq=((sh_uint64)ecx*ebx)/eax; + } else { + return SH_STATUS_UNAVAILABLE; + } + is_cpu_freq_provided=SH_TRUE; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_tsc_devs_query(char *sub_path,sh_devs_RESULT *result) { + if (sub_path==SH_NULLPTR || result==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 path_len=sh_string_len(sub_path); + if (path_len==0 || path_len>256) return SH_STATUS_INVALID_PARAMETER; + if (sh_string_compare(sub_path,"/kernel-init-tsc",16)) { + if (path_len==16) { + result->type=SH_DEVS_VALUE; + result->value=kernel_start_tsc; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/cpu-freq",9)) { + if (path_len==9) { + result->type=SH_DEVS_VALUE; + result->value=internal_cpu_freq; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/is-cpu-freq-provided",21)) { + if (path_len==21) { + result->type=SH_DEVS_BOOL; + result->value=is_cpu_freq_provided; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else { + return SH_STATUS_NOT_FOUND; + } +} diff --git a/shelter/lib/src/devs/acpi.c b/shelter/lib/src/devs/acpi.c new file mode 100644 index 0000000..f46ed97 --- /dev/null +++ b/shelter/lib/src/devs/acpi.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "devs/acpi.h" +#include "memory/memory.h" +#include "kernel/log.h" +static sh_uint8 sh_acpi_internal_checksum(sh_uint8 *ptr,sh_uint64 size) { + sh_uint8 sum=0; + for (sh_uint64 i=0;isignature[i]!=sig[i]) return SH_STATUS_INVALID_SIGNATURE; + } + if (sh_acpi_internal_checksum((sh_uint8*)v1,sizeof(sh_acpi_RSDP_V1))!=0) return SH_STATUS_INVALID_CHECKSUM; + if (acpi_ver==1 || v1->revision==0) { + out->rsdt=v1->rsdt_address; + out->xsdt=0; + return SH_STATUS_SUCCESS; + } + sh_acpi_RSDP_V2 *v2=(sh_acpi_RSDP_V2 *)rsdp; + if (v2->lengthlength)!=0) return SH_STATUS_INVALID_CHECKSUM; + if (acpi_ver==1 && v1->revision>=2) return SH_STATUS_INVALID_STATE; + out->rsdt=v2->first_part.rsdt_address; + out->xsdt=v2->xsdt_address; + if (out->xsdt==0) return SH_STATUS_NOT_FOUND; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_acpi_parse_xsdt(sh_uint64 xsdt,sh_acpi_ACPI_XSDT_BODY *xsdt_body) { + if (xsdt==0 || xsdt_body==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 page=xsdt& ~0xFFFULL; + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"XSDT: 0x%x; XSDT aligned: 0x%x\n",xsdt,page); + SH_STATUS status=sh_memory_identity_map(page,1,SH_PAGE_PRESENT | SH_PAGE_NX); + if (sh_status_error(status)) return status; + sh_acpi_ACPI_XSDT_HEADER *header=(sh_acpi_ACPI_XSDT_HEADER*)xsdt; + if (header->signature[0]!='X' || header->signature[1]!='S' ||header->signature[2]!='D' ||header->signature[3]!='T') return SH_STATUS_INVALID_SIGNATURE; + if (header->lengthlength)!=0) return SH_STATUS_INVALID_CHECKSUM; + sh_uint64 count=(header->length-sizeof(sh_acpi_ACPI_XSDT_HEADER))/8; + if (count==0) return SH_STATUS_NOT_FOUND; + sh_uint64 *entries=(sh_uint64*)(header+1); + sh_uint64 entries_bytes=count*sizeof(sh_uint64); + sh_uint64 entries_start=(sh_uint64)entries & ~0xFFFULL; + sh_uint64 entries_end=((sh_uint64)entries+entries_bytes+0xFFF)&~0xFFFULL; + sh_uint64 pages=(entries_end-entries_start)>>12; + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"XSDT entries: 0x%x; XSDT entries aligned: 0x%x\n",entries,entries_start); + status=sh_memory_identity_map(entries_start,pages,SH_PAGE_PRESENT | SH_PAGE_NX); + if (sh_status_error(status) && status!=SH_STATUS_ERROR_VA_FULLY_MAPPED) return status; + sh_uint64 valid=0; + for (sh_uint64 i=0;ientries=entries; + xsdt_body->entry_count=count; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_acpi_parse_tables(sh_acpi_ACPI_XSDT_BODY *xsdt_body,sh_acpi_ACPI_TABLES *acpi_tables) { + if (xsdt_body==SH_NULLPTR || acpi_tables==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + acpi_tables->madt_physical_address=0; + for (sh_uint64 i=0;ientry_count;i++) { + sh_uint64 phys=xsdt_body->entries[i]; + if (phys==0) { + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"Table #%8u: empty, skipping.\n",i); + continue; + } + sh_uint64 page=phys& ~0xfffull; + SH_STATUS status=sh_memory_identity_map(page,1,SH_PAGE_PRESENT | SH_PAGE_NX); + if (sh_status_error(status)) return status; + sh_acpi_TABLE_HEADER *header=(sh_acpi_TABLE_HEADER*)phys; + if (header->lengthsignature[0]=='A' && header->signature[1]=='P' && header->signature[2]=='I' && header->signature[3]=='C') { + if (acpi_tables->madt_physical_address!=0) { + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"Duplicated table with APIC signature, skipping.\n"); + continue; + } else { + acpi_tables->madt_physical_address=phys; + } + } + char table_signature[5]={0}; + sh_mem_copy(table_signature,header->signature,sizeof(header->signature)); + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"Table #%8u: Signature \"%s\". Stored at 0x%x\n",i,table_signature,(sh_uint64)header); + } + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/devs/acpi_tables/madt.c b/shelter/lib/src/devs/acpi_tables/madt.c new file mode 100644 index 0000000..413e3e6 --- /dev/null +++ b/shelter/lib/src/devs/acpi_tables/madt.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "devs/acpi_tables/madt.h" +#include "devs/apic/lapic.h" +#include "devs/apic/ioapic.h" +#include "memory/memory.h" +#include "kernel/log.h" +#include "irq/gsi.h" +SH_STATUS sh_acpi_madt_parse(sh_uint64 madt_ptr) { + if (madt_ptr==0) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 page=madt_ptr & ~0xfffull; + SH_STATUS status=sh_memory_identity_map(page,1,SH_PAGE_PRESENT | SH_PAGE_NX); + if (sh_status_error(status) && status!=SH_STATUS_ERROR_VA_FULLY_MAPPED) return status; + sh_acpi_madt_MADT *madt=(sh_acpi_madt_MADT*)madt_ptr; + if (madt->header.signature[0]!='A' || madt->header.signature[1]!='P' || madt->header.signature[2]!='I' || madt->header.signature[3]!='C') return SH_STATUS_INVALID_SIGNATURE; + if (madt->header.lengthheader.length; + sh_uint16 max_apic_id=0; + sh_uint16 max_acpi_processor_id=0; + sh_uint8 max_ioapic_id=0; + status=sh_gsi_iso_array_init(); + if (sh_status_error(status)) return status; + while (offsetlength==0) break; + switch (header->type) { + case 0: { + sh_acpi_madt_LAPIC *lapic=(sh_acpi_madt_LAPIC*)header; + if (lapic->flags & 1) { + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"Found LAPIC with CPU: apic_id=%1u acpi_processor_id=%1u flags=0x%4U\n",lapic->apic_id,lapic->acpi_processor_id,lapic->flags); + if (lapic->apic_id>max_apic_id) max_apic_id=lapic->apic_id; + if (lapic->acpi_processor_id>max_acpi_processor_id) max_acpi_processor_id=lapic->acpi_processor_id; + } else { + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"Found LAPIC without CPU: apic_id=%1u acpi_processor_id=%1u flags=0x%4U\n",lapic->apic_id,lapic->acpi_processor_id,lapic->flags); + } + break; + } + case 1: { + sh_acpi_madt_IOAPIC *ioapic=(sh_acpi_madt_IOAPIC*)header; + if (ioapic->ioapic_id>max_ioapic_id) max_ioapic_id=ioapic->ioapic_id; + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"Found IOAPIC: ioapic_id=%1u ioapic_address=0x%4U gsi_base=%4U\n",ioapic->ioapic_id,ioapic->ioapic_address,ioapic->global_system_interrupt_base); + break; + } + case 2: { + sh_acpi_madt_ISO *iso=(sh_acpi_madt_ISO*)header; + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"Found interrupt source override: bus=%1u source=%1u gsi=%4u flags=0x%2U\n",iso->bus,iso->source,iso->gsi,iso->flags); + break; + } + default: + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"Found unknow type: %1u\n",header->type); + break; + } + offset+=header->length; + } + status=sh_lapic_init_devs(max_apic_id,max_acpi_processor_id); + if (sh_status_error(status)) return status; + status=sh_ioapic_init_devs(max_ioapic_id); + if (sh_status_error(status)) return status; + offset=sizeof(sh_acpi_madt_MADT); + end=madt->header.length; + while (offsetlength==0) break; + switch (header->type) { + case 0: { + sh_acpi_madt_LAPIC *lapic=(sh_acpi_madt_LAPIC*)header; + if (lapic->flags & 1) { + sh_lapic_DEVICE *lapic_dev=sh_malloc(sizeof(sh_lapic_DEVICE)); + if (!lapic_dev) return SH_STATUS_ERROR_NULLPTR_RETURNED; + status=sh_lapic_init(madt->local_apic_address,0xFF,lapic->apic_id,lapic->acpi_processor_id,lapic->flags,lapic_dev); + if (sh_status_error(status)) return status; + status=sh_lapic_bind(lapic_dev); + if (sh_status_error(status)) return status; + } else { + // ignore + } + break; + } + case 1: { + sh_acpi_madt_IOAPIC *ioapic=(sh_acpi_madt_IOAPIC*)header; + sh_ioapic_DEVICE *ioapic_dev=sh_malloc(sizeof(sh_ioapic_DEVICE)); + if (!ioapic_dev) return SH_STATUS_ERROR_NULLPTR_RETURNED; + status=sh_ioapic_init(ioapic->ioapic_address,ioapic->ioapic_id,ioapic->global_system_interrupt_base,ioapic_dev); + if (sh_status_error(status)) return status; + status=sh_ioapic_bind(ioapic_dev); + if (sh_status_error(status)) return status; + break; + } + case 2: { + sh_acpi_madt_ISO *iso=(sh_acpi_madt_ISO*)header; + status=sh_gsi_iso_register(iso->bus,iso->source,iso->gsi,iso->flags); + if (sh_status_error(status)) return status; + break; + } + default: + // ignore + break; + } + offset+=header->length; + } + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/devs/apic/ioapic.c b/shelter/lib/src/devs/apic/ioapic.c new file mode 100644 index 0000000..31b2e39 --- /dev/null +++ b/shelter/lib/src/devs/apic/ioapic.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "devs/apic/ioapic.h" +#include "memory/memory.h" +#include "kernel/log.h" +typedef struct { + sh_ioapic_DEVICE **by_ioapic_id; + sh_uint64 max_ioapic_id; + sh_uint64 ioapic_count; +} ioapic_devs_template; +ioapic_devs_template ioapic_devs={0}; +static inline sh_uint32 sh_ioapic_read(sh_ioapic_DEVICE *ioapic,sh_uint32 reg) { + *(volatile sh_uint32*)((sh_uint8*)ioapic->base+SH_IOAPIC_OFFSET_IOREGSEL)=reg; + return *(volatile sh_uint32*)((sh_uint8*)ioapic->base+SH_IOAPIC_OFFSET_IOWIN); +} +static inline void sh_ioapic_write(sh_ioapic_DEVICE *ioapic,sh_uint32 reg,sh_uint32 value) { + *(volatile sh_uint32*)((sh_uint8*)ioapic->base+SH_IOAPIC_OFFSET_IOREGSEL)=reg; + *(volatile sh_uint32*)((sh_uint8*)ioapic->base+SH_IOAPIC_OFFSET_IOWIN)=value; +} +SH_STATUS sh_ioapic_init(sh_uint32 base,sh_uint8 ioapic_id,sh_uint32 gsi_base,sh_ioapic_DEVICE *ioapic) { + if (ioapic==SH_NULLPTR || base==0) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 page=base& ~0xfffull; + SH_STATUS status=sh_memory_identity_map(page,1,SH_PAGE_RW | SH_PAGE_PRESENT | SH_PAGE_NX | SH_PAGE_PCD); + if (sh_status_error(status) && status!=SH_STATUS_ERROR_VA_FULLY_MAPPED) return status; + ioapic->base=(volatile sh_uint32*)(sh_uint64)base; + ioapic->ioapic_id=ioapic_id; + ioapic->gsi_base=gsi_base; + ioapic->gsi_count=0; + ioapic->lock=SH_LOCK_LOCAL(); + sh_uint32 ver=sh_ioapic_read(ioapic,SH_IOAPIC_REGISTER_IOAPICVER); + sh_uint32 max_redir=(ver>>16)&0xFF; + ioapic->gsi_count=max_redir+1; + sh_log_fdebug(SH_LOG_SOURCE_ACPI,"IOAPIC with id %1u: [%4u - %4u]\n",ioapic->ioapic_id,ioapic->gsi_base,ioapic->gsi_base+ioapic->gsi_count-1); + sh_uint32 id_reg=sh_ioapic_read(ioapic,SH_IOAPIC_REGISTER_IOAPICID); + sh_uint8 hw_id=(id_reg>>24)&0x0F; + if (hw_id!=ioapic_id) { + sh_log_fwarning(SH_LOG_SOURCE_ACPI,"IOAPIC of IOAPIC id %1u doesn't provide the same id in his hardware register: %4u.\n",ioapic_id,hw_id); + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_ioapic_init_devs(sh_uint8 max_ioapic_id) { + sh_ioapic_DEVICE **ioapic_ptr_by_ioapic_id=sh_malloc((max_ioapic_id+1)*sizeof(sh_ioapic_DEVICE*)); + if (!ioapic_ptr_by_ioapic_id) return SH_STATUS_ERROR_NULLPTR_RETURNED; + sh_mem_set_8((sh_uint8*)ioapic_ptr_by_ioapic_id,0x0,(max_ioapic_id+1)*sizeof(sh_ioapic_DEVICE*)); + ioapic_devs.by_ioapic_id=ioapic_ptr_by_ioapic_id; + ioapic_devs.max_ioapic_id=max_ioapic_id; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_ioapic_bind(sh_ioapic_DEVICE *ioapic_dev) { + if (ioapic_dev==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + if (ioapic_devs.by_ioapic_id==SH_NULLPTR) return SH_STATUS_DEVS_NOT_INITIALIZED; + ioapic_devs.by_ioapic_id[ioapic_dev->ioapic_id]=ioapic_dev; + ioapic_devs.ioapic_count++; + return SH_STATUS_SUCCESS; +} +sh_ioapic_DEVICE *sh_ioapic_get_dev_ioapic_id(sh_uint64 ioapic_id) { + if (ioapic_id>ioapic_devs.max_ioapic_id) return SH_NULLPTR; + return ioapic_devs.by_ioapic_id[ioapic_id]; +} +SH_STATUS sh_ioapic_read_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry) { + if (!ioapic_dev || !entry) return SH_STATUS_INVALID_PARAMETER; + if (gsigsi_base) return SH_STATUS_INVALID_PARAMETER; + sh_uint32 index=gsi-ioapic_dev->gsi_base; + if (index>=ioapic_dev->gsi_count) return SH_STATUS_INVALID_PARAMETER; + sh_uint32 low_reg=SH_IOAPIC_REGISTER_IOREDTBL_BASE+(index*2); + sh_uint32 high_reg=low_reg+1; + sh_spin_lock(&ioapic_dev->lock); + entry->low=sh_ioapic_read(ioapic_dev,low_reg); + entry->high=sh_ioapic_read(ioapic_dev,high_reg); + sh_spin_unlock(&ioapic_dev->lock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_ioapic_mask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi) { + if (!dev) return SH_STATUS_INVALID_PARAMETER; + sh_ioapic_IOREDTBL_ENTRY e; + SH_STATUS status=sh_ioapic_read_ioredtbl_entry(dev,gsi,&e); + if (status!=SH_STATUS_SUCCESS) return status; + e.low|=(1<<16); + return sh_ioapic_write_ioredtbl_entry(dev,gsi,&e); +} +SH_STATUS sh_ioapic_unmask_gsi(sh_ioapic_DEVICE *dev,sh_uint32 gsi) { + if (!dev) return SH_STATUS_INVALID_PARAMETER; + sh_ioapic_IOREDTBL_ENTRY e; + SH_STATUS status=sh_ioapic_read_ioredtbl_entry(dev,gsi,&e); + if (status!=SH_STATUS_SUCCESS) return status; + e.low&= ~(1U<<16); + return sh_ioapic_write_ioredtbl_entry(dev,gsi,&e); +} +SH_STATUS sh_ioapic_write_ioredtbl_entry(sh_ioapic_DEVICE *ioapic_dev,sh_uint32 gsi,sh_ioapic_IOREDTBL_ENTRY *entry) { + if (!ioapic_dev || !entry) return SH_STATUS_INVALID_PARAMETER; + if (gsigsi_base) return SH_STATUS_INVALID_PARAMETER; + sh_uint32 index=gsi-ioapic_dev->gsi_base; + if (index>=ioapic_dev->gsi_count) return SH_STATUS_INVALID_PARAMETER; + sh_uint32 low_reg=SH_IOAPIC_REGISTER_IOREDTBL_BASE+(index*2); + sh_uint32 high_reg=low_reg+1; + sh_spin_lock(&ioapic_dev->lock); + sh_ioapic_write(ioapic_dev,high_reg,entry->high); + sh_ioapic_write(ioapic_dev,low_reg,entry->low); + sh_spin_unlock(&ioapic_dev->lock); + return SH_STATUS_SUCCESS; +} +sh_ioapic_DEVICE *sh_ioapic_get_dev_by_gsi(sh_uint32 gsi) { + if (ioapic_devs.by_ioapic_id==SH_NULLPTR) return SH_NULLPTR; + for (sh_uint64 i=0;i<=ioapic_devs.max_ioapic_id;i++) { + sh_ioapic_DEVICE *dev=ioapic_devs.by_ioapic_id[i]; + if (!dev) continue; + if (gsi>=dev->gsi_base && gsi<(dev->gsi_base+dev->gsi_count)) { + return dev; + } + } + return SH_NULLPTR; +} +SH_STATUS sh_ioapic_mask_all() { + if (ioapic_devs.by_ioapic_id==SH_NULLPTR) return SH_STATUS_DEVS_NOT_INITIALIZED; + for (sh_uint64 i=0;i<=ioapic_devs.max_ioapic_id;i++) { + sh_ioapic_DEVICE *dev=ioapic_devs.by_ioapic_id[i]; + if (!dev) continue; + for (sh_uint32 j=0;jgsi_count;j++) { + sh_uint32 gsi=dev->gsi_base+j; + SH_STATUS status=sh_ioapic_mask_gsi(dev,gsi); + if (sh_status_error(status)) return status; + } + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_ioapic_devs_query(char *sub_path,sh_devs_RESULT *result) { + if (sub_path==SH_NULLPTR || result==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 path_len=sh_string_len(sub_path); + if (path_len==0 || path_len>256) return SH_STATUS_INVALID_PARAMETER; + if (ioapic_devs.by_ioapic_id==SH_NULLPTR) return SH_STATUS_DEVS_NOT_INITIALIZED; + if (sh_string_compare(sub_path,"/count",6)) { + if (path_len==6) { + result->type=SH_DEVS_VALUE; + result->value=ioapic_devs.ioapic_count; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/max-ioapic-id",14)) { + if (path_len==14) { + result->type=SH_DEVS_VALUE; + result->value=ioapic_devs.max_ioapic_id; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/by-ioapic-id/",14)) { + if (path_len>14 && path_len<=34) { + sh_uint64 remaining_text=sh_string_len(sub_path)-sh_string_len("/by-ioapic-id/"); + char ioapic_id_str[22]; + sh_string_substring(sub_path,sh_string_len("/by-ioapic-id/"),remaining_text,ioapic_id_str); + sh_uint64 ioapic_id=sh_string_to_uint64(ioapic_id_str); + if (ioapic_id>ioapic_devs.max_ioapic_id) return SH_STATUS_NOT_FOUND; + result->type=SH_DEVS_IOAPIC; + result->value=(sh_uint64)ioapic_devs.by_ioapic_id[ioapic_id]; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/by-gsi/",8)) { + if (path_len>8 && path_len<=28) { + sh_uint64 remaining_text=sh_string_len(sub_path)-sh_string_len("/by-gsi/"); + char gsi_str[22]; + sh_string_substring(sub_path,sh_string_len("/by-gsi/"),remaining_text,gsi_str); + sh_uint64 gsi=sh_string_to_uint64(gsi_str); + result->type=SH_DEVS_IOAPIC; + result->value=(sh_uint64)sh_ioapic_get_dev_by_gsi((sh_uint32)gsi); + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else { + return SH_STATUS_NOT_FOUND; + } + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/devs/apic/lapic.c b/shelter/lib/src/devs/apic/lapic.c new file mode 100644 index 0000000..6c289dd --- /dev/null +++ b/shelter/lib/src/devs/apic/lapic.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "devs/apic/lapic.h" +#include "memory/memory.h" +#include "irq/irq.h" +#include "cpu/tsc.h" +typedef struct { + sh_lapic_DEVICE **by_apic_id; + sh_lapic_DEVICE **by_cpu_id; + sh_uint64 max_apic_id; + sh_uint64 max_acpi_processor_id; + sh_uint64 lapic_count; +} lapic_devs_template; +lapic_devs_template lapic_devs={0}; +sh_uint64 lapic_frequency=0; +static inline sh_uint32 sh_lapic_read(sh_lapic_DEVICE *lapic,sh_uint32 reg) { + return *(volatile sh_uint32*)((sh_uint8*)lapic->base+reg); +} +static inline void sh_lapic_write(sh_lapic_DEVICE *lapic,sh_uint32 reg,sh_uint32 value) { + *(volatile sh_uint32*)((sh_uint8*)lapic->base+reg)=value; +} +SH_STATUS sh_lapic_init(sh_uint64 lapic_phys,sh_uint8 spurious_vector,sh_uint8 apic_id,sh_uint8 apic_processor_id,sh_uint32 flags,sh_lapic_DEVICE *lapic) { + if (lapic==SH_NULLPTR || lapic_phys==0) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 page=lapic_phys& ~0xfffull; + SH_STATUS status=sh_memory_identity_map(page,1,SH_PAGE_RW | SH_PAGE_PRESENT | SH_PAGE_NX | SH_PAGE_PCD); + if (sh_status_error(status) && status!=SH_STATUS_ERROR_VA_FULLY_MAPPED) return status; + lapic->base=(volatile sh_uint32*)lapic_phys; + lapic->spurious_vector=spurious_vector; + lapic->apic_id=apic_id; + lapic->acpi_processor_id=apic_processor_id; + lapic->flags=flags; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_lapic_init_dev(sh_uint8 spurious_vector,sh_lapic_DEVICE *lapic) { + if (lapic==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint32 svr=spurious_vector|(1<<8); + sh_lapic_write(lapic,SH_LAPIC_OFFSET_SVR,svr); + sh_lapic_write(lapic,SH_LAPIC_OFFSET_ESR,0); + sh_lapic_write(lapic,SH_LAPIC_OFFSET_ESR,0); + sh_lapic_write(lapic,SH_LAPIC_OFFSET_EOI,0); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_lapic_init_devs(sh_uint16 max_lapic_id,sh_uint16 max_acpi_processor_id) { + if (max_lapic_id==0 || max_lapic_id>256) return SH_STATUS_INVALID_PARAMETER; + sh_lapic_DEVICE **lapic_ptr_by_apic_id=sh_malloc((max_lapic_id+1)*sizeof(sh_lapic_DEVICE*)); + if (!lapic_ptr_by_apic_id) return SH_STATUS_ERROR_NULLPTR_RETURNED; + sh_mem_set_8((sh_uint8*)lapic_ptr_by_apic_id,0x0,(max_lapic_id+1)*sizeof(sh_lapic_DEVICE*)); + lapic_devs.by_apic_id=lapic_ptr_by_apic_id; + sh_lapic_DEVICE **lapic_ptr_by_cpu_id=sh_malloc((max_acpi_processor_id+1)*sizeof(sh_lapic_DEVICE*)); + if (!lapic_ptr_by_cpu_id) return SH_STATUS_ERROR_NULLPTR_RETURNED; + sh_mem_set_8((sh_uint8*)lapic_ptr_by_cpu_id,0x0,(max_acpi_processor_id+1)*sizeof(sh_lapic_DEVICE*)); + lapic_devs.by_cpu_id=lapic_ptr_by_cpu_id; + lapic_devs.max_apic_id=max_lapic_id; + lapic_devs.max_acpi_processor_id=max_acpi_processor_id; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_lapic_bind(sh_lapic_DEVICE *lapic_dev) { + if (lapic_dev==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + if (lapic_devs.by_apic_id==SH_NULLPTR || lapic_devs.by_cpu_id==SH_NULLPTR) return SH_STATUS_DEVS_NOT_INITIALIZED; + lapic_devs.by_apic_id[lapic_dev->apic_id]=lapic_dev; + lapic_devs.by_cpu_id[lapic_dev->acpi_processor_id]=lapic_dev; + lapic_devs.lapic_count++; + return SH_STATUS_SUCCESS; +} +void sh_lapic_eoi(sh_lapic_DEVICE *lapic) { + sh_lapic_write(lapic,SH_LAPIC_OFFSET_EOI,0); +} +sh_lapic_DEVICE *sh_lapic_get_dev_apic_id(sh_uint64 apic_id) { + if (lapic_devs.by_apic_id==SH_NULLPTR) return SH_NULLPTR; + if (apic_id>lapic_devs.max_apic_id) return SH_NULLPTR; + return lapic_devs.by_apic_id[apic_id]; +} +sh_lapic_DEVICE *sh_lapic_get_dev_acpi_cpu_id(sh_uint64 acpi_processor_id) { + if (lapic_devs.by_cpu_id==SH_NULLPTR) return SH_NULLPTR; + if (acpi_processor_id>lapic_devs.max_apic_id) return SH_NULLPTR; + return lapic_devs.by_apic_id[acpi_processor_id]; +} +SH_STATUS sh_lapic_timer_one_shot(sh_lapic_DEVICE *lapic_dev,sh_uint32 initial_value) { + if (lapic_dev==SH_NULLPTR || initial_value==0) return SH_STATUS_INVALID_PARAMETER; + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_LVT_TIMER,(1<<16)); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_TIMER_DIV,SH_LAPIC_TIMER_DIVIDER); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_TIMER_INIT,initial_value); + sh_uint32 lvt=(0xFE)|(0<<17)|(0<<16); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_LVT_TIMER,lvt); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_lapic_calibrate(sh_lapic_DEVICE *lapic_dev,sh_uint64 cpu_freq) { + if (!lapic_dev) return SH_STATUS_INVALID_PARAMETER; + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_TIMER_DIV,SH_LAPIC_TIMER_DIVIDER); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_LVT_TIMER,(1<<16)); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_TIMER_INIT,0xFFFFFFFF); + sh_uint64 tsc_start=sh_tsc_read_tsc(); + sh_uint32 lapic_start=sh_lapic_read(lapic_dev,SH_LAPIC_OFFSET_TIMER_CURR); + for (volatile int i=0;i<10000000;i++) __asm__ volatile("pause"); + sh_uint32 lapic_end=sh_lapic_read(lapic_dev,SH_LAPIC_OFFSET_TIMER_CURR); + sh_uint64 tsc_end=sh_tsc_read_tsc(); + sh_uint32 lapic_delta=lapic_start-lapic_end; + sh_uint64 tsc_delta=tsc_end-tsc_start; + if (!tsc_delta || !lapic_delta) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 lapic_freq=(lapic_delta*cpu_freq)/tsc_delta; + lapic_frequency=lapic_freq; + return SH_STATUS_SUCCESS; +} +sh_uint64 sh_lapic_get_frequency() { + return lapic_frequency; +} +SH_STATUS sh_lapic_timer_one_shot_us(sh_lapic_DEVICE *lapic_dev,sh_uint64 microseconds_count) { + sh_asm_sti(); + if (lapic_frequency==0) return SH_STATUS_INVALID_STATE; + if (microseconds_count==0) return SH_STATUS_SUCCESS; + sh_uint64 ticks=(lapic_frequency*microseconds_count)/1000000ULL; + if (ticks>0xFFFFFFFF) return SH_STATUS_TOO_MUCH_DATA; + if (ticks==0) ticks=1; + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_LVT_TIMER,(1<<16)); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_LVT_TIMER,0xFE); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_TIMER_INIT,(sh_uint32)ticks); + sh_irq_start_timer(); + while (sh_irq_get_timer_state()) { + __asm__ volatile ("hlt"); + } + return SH_STATUS_SUCCESS; +} +sh_lapic_DEVICE **sh_lapic_get_by_apic_id_array() { + return lapic_devs.by_apic_id; +} +sh_uint64 sh_lapic_get_max_apic_id() { + return lapic_devs.max_apic_id; +} +sh_uint64 sh_lapic_get_max_acpi_processor_id() { + return lapic_devs.max_acpi_processor_id; +} +sh_uint64 sh_lapic_get_lapic_count() { + return lapic_devs.lapic_count; +} +sh_bool sh_lapic_ipi_is_busy(sh_lapic_DEVICE *lapic_dev) { + if (!lapic_dev) return SH_FALSE; + return (sh_lapic_read(lapic_dev,SH_LAPIC_OFFSET_ICR_LOW)&(1u<<12))?SH_TRUE:SH_FALSE; +} +sh_int16 sh_lapic_get_current_core() { + sh_lapic_DEVICE *lapic_dev=sh_lapic_get_dev_apic_id(0); + if (!lapic_dev) return -1; + return (sh_int16)((sh_lapic_read(lapic_dev,SH_LAPIC_OFFSET_ID)>>24)&0xFF); +} +SH_STATUS sh_lapic_send_fixed_ipi(sh_lapic_DEVICE *lapic_dev,sh_uint8 vector,sh_uint32 destination_mode,sh_int16 target_lapic_id) { + sh_uint32 icr_low=0; + sh_uint32 icr_high=0; + if (!lapic_dev) return SH_STATUS_INVALID_PARAMETER; + if (vector<16) return SH_STATUS_INVALID_PARAMETER; + switch (destination_mode) { + case SH_LAPIC_IPI_DESTINATION_SPECIFIC: + if (target_lapic_id==SH_LAPIC_IPI_NO_DESTINATION) + return SH_STATUS_INVALID_PARAMETER; + break; + case SH_LAPIC_IPI_DESTINATION_SELF: + case SH_LAPIC_IPI_DESTINATION_ALL: + case SH_LAPIC_IPI_DESTINATION_ALL_EXCLUDING_SELF: + if (target_lapic_id!=SH_LAPIC_IPI_NO_DESTINATION) + return SH_STATUS_INVALID_PARAMETER; + break; + default: + return SH_STATUS_INVALID_PARAMETER; + } + while (sh_lapic_ipi_is_busy(lapic_dev)); + if (destination_mode==SH_LAPIC_IPI_DESTINATION_SPECIFIC) icr_high=((sh_uint32)target_lapic_id&0xFF)<<24; + icr_low=vector|(SH_LAPIC_IPI_TYPE_FIXED<<8)|(1u<<14)|destination_mode; + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_ICR_HIGH,icr_high); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_ICR_LOW,icr_low); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_lapic_send_ipi(sh_lapic_DEVICE *lapic_dev,sh_uint32 ipi_type,sh_uint32 destination_mode,sh_int16 target_lapic_id,sh_page_PHYSICAL_ADDRESS start_address) { + sh_uint32 icr_low=0; + sh_uint32 icr_high=0; + if (!lapic_dev) return SH_STATUS_INVALID_PARAMETER; + if (ipi_type!=SH_LAPIC_IPI_TYPE_INIT && ipi_type!=SH_LAPIC_IPI_TYPE_STARTUP && ipi_type!=SH_LAPIC_IPI_TYPE_NMI) return SH_STATUS_INVALID_PARAMETER; + if (ipi_type==SH_LAPIC_IPI_TYPE_STARTUP) { + if (start_address==0) return SH_STATUS_INVALID_PARAMETER; + if (start_address&0xFFF) return SH_STATUS_INVALID_PARAMETER; + if ((start_address>>12)>0xFF) return SH_STATUS_INVALID_PARAMETER; + } else { + if (start_address!=0) return SH_STATUS_INVALID_PARAMETER; + } + switch (destination_mode) { + case SH_LAPIC_IPI_DESTINATION_SPECIFIC: + if (target_lapic_id==SH_LAPIC_IPI_NO_DESTINATION) + return SH_STATUS_INVALID_PARAMETER; + break; + case SH_LAPIC_IPI_DESTINATION_SELF: + case SH_LAPIC_IPI_DESTINATION_ALL: + case SH_LAPIC_IPI_DESTINATION_ALL_EXCLUDING_SELF: + if (target_lapic_id!=SH_LAPIC_IPI_NO_DESTINATION) + return SH_STATUS_INVALID_PARAMETER; + break; + default: + return SH_STATUS_INVALID_PARAMETER; + } + while (sh_lapic_ipi_is_busy(lapic_dev)); + if (destination_mode==SH_LAPIC_IPI_DESTINATION_SPECIFIC) icr_high=((sh_uint32)target_lapic_id&0xFF)<<24; + icr_low=(ipi_type<<8)|(1u<<14)|destination_mode; + if (ipi_type==SH_LAPIC_IPI_TYPE_STARTUP) icr_low|=(sh_uint32)(start_address>>12); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_ICR_HIGH,icr_high); + sh_lapic_write(lapic_dev,SH_LAPIC_OFFSET_ICR_LOW,icr_low); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_lapic_devs_query(char *sub_path,sh_devs_RESULT *result) { + if (sub_path==SH_NULLPTR || result==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 path_len=sh_string_len(sub_path); + if (path_len==0 || path_len>256) return SH_STATUS_INVALID_PARAMETER; + if (lapic_devs.by_apic_id==SH_NULLPTR || lapic_devs.by_cpu_id==SH_NULLPTR) return SH_STATUS_DEVS_NOT_INITIALIZED; + if (sh_string_compare(sub_path,"/count",6)) { + if (path_len==6) { + result->type=SH_DEVS_VALUE; + result->value=lapic_devs.lapic_count; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/timer-frequency",16)) { + if (path_len==16) { + result->type=SH_DEVS_VALUE; + result->value=lapic_frequency; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/max-apic-id",12)) { + if (path_len==12) { + result->type=SH_DEVS_VALUE; + result->value=lapic_devs.max_apic_id; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/max-acpi-id",12)) { + if (path_len==12) { + result->type=SH_DEVS_VALUE; + result->value=lapic_devs.max_acpi_processor_id; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/base-address",13)) { + if (path_len==13) { + result->type=SH_DEVS_VALUE; + result->value=(sh_uint64)sh_lapic_get_dev_apic_id(sh_smp_gs_base()->lapic_id)->base; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/this-cpu-lapic",15)) { + if (path_len==15) { + result->type=SH_DEVS_LAPIC; + result->value=(sh_uint64)sh_lapic_get_dev_apic_id(sh_smp_gs_base()->lapic_id); + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/by-apic-id/",12)) { + if (path_len>12 && path_len<=32) { + sh_uint64 remaining_text=sh_string_len(sub_path)-sh_string_len("/by-apic-id/"); + char apic_id_str[22]; + sh_string_substring(sub_path,sh_string_len("/by-apic-id/"),remaining_text,apic_id_str); + sh_uint64 apic_id=sh_string_to_uint64(apic_id_str); + if (apic_id>lapic_devs.max_apic_id) return SH_STATUS_NOT_FOUND; + result->type=SH_DEVS_LAPIC; + result->value=(sh_uint64)lapic_devs.by_apic_id[apic_id]; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/by-acpi-id/",12)) { + if (path_len>12 && path_len<=32) { + sh_uint64 remaining_text=sh_string_len(sub_path)-sh_string_len("/by-acpi-id/"); + char acpi_id_str[22]; + sh_string_substring(sub_path,sh_string_len("/by-acpi-id/"),remaining_text,acpi_id_str); + sh_uint64 acpi_id=sh_string_to_uint64(acpi_id_str); + if (acpi_id>lapic_devs.max_apic_id) return SH_STATUS_NOT_FOUND; + result->type=SH_DEVS_LAPIC; + result->value=(sh_uint64)lapic_devs.by_cpu_id[acpi_id]; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else { + return SH_STATUS_NOT_FOUND; + } + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/devs/devs.c b/shelter/lib/src/devs/devs.c new file mode 100644 index 0000000..1f615a8 --- /dev/null +++ b/shelter/lib/src/devs/devs.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "devs/devs.h" +#include "devs/apic/lapic.h" +#include "devs/apic/ioapic.h" +#include "std/smp.h" +SH_STATUS sh_devs_query(char *path,sh_devs_RESULT *result) { + if (path==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 path_len=sh_string_len(path); + if (path_len==0 || path_len>256) return SH_STATUS_INVALID_PARAMETER; + if (sh_string_compare(path,"$apic/lapic",11)) { + if (path_len>11) { + sh_uint64 remaining_text=sh_string_len(path)-sh_string_len("$apic/lapic"); + return sh_lapic_devs_query(sh_string_substring(path,sh_string_len("$apic/lapic"),remaining_text,sh_smp_gs_base()->per_cpu->temp_buffer),result); + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(path,"$apic/ioapic",12)) { + if (path_len>12) { + sh_uint64 remaining_text=sh_string_len(path)-sh_string_len("$apic/ioapic"); + return sh_ioapic_devs_query(sh_string_substring(path,sh_string_len("$apic/ioapic"),remaining_text,sh_smp_gs_base()->per_cpu->temp_buffer),result); + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(path,"$tsc",4)) { + if (path_len>4) { + sh_uint64 remaining_text=sh_string_len(path)-sh_string_len("$tsc"); + return sh_tsc_devs_query(sh_string_substring(path,sh_string_len("$tsc"),remaining_text,sh_smp_gs_base()->per_cpu->temp_buffer),result); + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(path,"$kernel/conf",12)) { + if (path_len>12) { + sh_uint64 remaining_text=sh_string_len(path)-sh_string_len("$kernel/conf"); + return sh_conf_devs_query(sh_string_substring(path,sh_string_len("$kernel/conf"),remaining_text,sh_smp_gs_base()->per_cpu->temp_buffer),result); + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(path,"$memory",7)) { + if (path_len>7) { + sh_uint64 remaining_text=sh_string_len(path)-sh_string_len("$memory"); + return sh_memory_devs_query(sh_string_substring(path,sh_string_len("$memory"),remaining_text,sh_smp_gs_base()->per_cpu->temp_buffer),result); + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(path,"$smp/cpu-count",14)) { + if (path_len==14) { + result->type=SH_DEVS_VALUE; + result->value=(sh_uint64)sh_smp_get_cpu_count(); + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else { + return SH_STATUS_NOT_FOUND; + } +} diff --git a/shelter/lib/src/devs/input/kbd.c b/shelter/lib/src/devs/input/kbd.c new file mode 100644 index 0000000..e714030 --- /dev/null +++ b/shelter/lib/src/devs/input/kbd.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "devs/input/kbd.h" +struct sh_kbd_DRIVER_HANDLE { + sh_uint8 id; + sh_uint32 generation; +}; +struct sh_kbd_CONSUMER_HANDLE { + sh_uint8 id; + sh_uint32 generation; + sh_uint32 read_index; +}; +typedef struct { + sh_kbd_DEVICE by_id[256]; + sh_uint32 id_generation[256]; + sh_uint64 bitmap[4]; + sh_uint64 keyboard_count; + sh_SPIN_LOCK id_manipulation_spinlock; + sh_bool ps2_registered; + sh_uint16 events_queue_capacity; + sh_bool is_kbd_devs_initialized; +} kbd_devs_template; +kbd_devs_template kbd_devs={.id_manipulation_spinlock=SH_LOCK()}; +SH_STATUS sh_kbd_init_devs() { + sh_spin_lock(&kbd_devs.id_manipulation_spinlock); + if (kbd_devs.is_kbd_devs_initialized) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_ALREADY_INITIALIZED; + } + sh_mem_set_8((sh_uint8*)kbd_devs.by_id,0x0,sizeof(sh_kbd_DEVICE)*256); + for (sh_iter64 i=0;i<256;i++) kbd_devs.by_id[i].spinlock=SH_LOCK_LOCAL(); + sh_mem_set_8((sh_uint8*)kbd_devs.id_generation,0x0,sizeof(sh_uint16)*256); + sh_mem_set_8((sh_uint8*)kbd_devs.bitmap,0x0,sizeof(sh_uint64)*4); + kbd_devs.keyboard_count=0; + kbd_devs.is_kbd_devs_initialized=SH_TRUE; + sh_devs_RESULT res; + SH_STATUS status=sh_devs_query("$kernel/conf/kbd-events-queue-capacity",&res); + if (sh_status_error(status)) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return status; + } + kbd_devs.events_queue_capacity=(sh_uint16)res.value; + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_kbd_register_ps2(sh_bool is_present,sh_kbd_DRIVER_HANDLE **handle) { + if (handle==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_spin_lock(&kbd_devs.id_manipulation_spinlock); + if (!kbd_devs.is_kbd_devs_initialized) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_DEVS_NOT_INITIALIZED; + } + if (kbd_devs.ps2_registered) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_ALREADY_INITIALIZED; + } + sh_uint8 id=0; + kbd_devs.bitmap[0]|=1ULL; + kbd_devs.id_generation[id]++; + sh_kbd_DEVICE *dev=&kbd_devs.by_id[id]; + dev->kbd_id=id; + dev->present=is_present; + dev->ver_maj=SH_FALSE; + dev->ver_num=SH_FALSE; + dev->shift=SH_FALSE; + dev->alt=SH_FALSE; + dev->ctrl=SH_FALSE; + dev->win=SH_FALSE; + dev->spinlock=SH_LOCK_LOCAL(); + sh_queue_KBD_EVENT *dev_queue=sh_malloc(sizeof(sh_queue_KBD_EVENT)); + if (!dev_queue) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_ERROR_NULLPTR_RETURNED; + } + SH_STATUS status=sh_queue_event_init(dev_queue,kbd_devs.events_queue_capacity); + if (sh_status_error(status)) { + sh_free(dev_queue); + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return status; + } + dev->events_queue=dev_queue; + kbd_devs.keyboard_count++; + kbd_devs.ps2_registered=SH_TRUE; + sh_kbd_DRIVER_HANDLE *driver_handle=sh_malloc(sizeof(sh_kbd_DRIVER_HANDLE)); + if (!dev_queue) { + status=sh_queue_event_destroy(dev_queue); + if (sh_status_error(status)) return status; + sh_free(dev_queue); + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_ERROR_NULLPTR_RETURNED; + } + driver_handle->id=id; + driver_handle->generation=kbd_devs.id_generation[id]; + *handle=driver_handle; + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_kbd_register(sh_bool is_present,sh_kbd_DRIVER_HANDLE **handle) { + if (handle==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_spin_lock(&kbd_devs.id_manipulation_spinlock); + if (!kbd_devs.is_kbd_devs_initialized) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_DEVS_NOT_INITIALIZED; + } + sh_uint8 id=0; + sh_bool found=SH_FALSE; + for (sh_uint32 i=1;i<256;i++) { + sh_uint32 idx=i/64; + sh_uint32 bit=i%64; + if (!(kbd_devs.bitmap[idx] & (1ULL<kbd_id=id; + dev->present=is_present; + dev->ver_maj=SH_FALSE; + dev->ver_num=SH_FALSE; + dev->shift=SH_FALSE; + dev->alt=SH_FALSE; + dev->ctrl=SH_FALSE; + dev->win=SH_FALSE; + dev->spinlock=SH_LOCK_LOCAL(); + kbd_devs.id_generation[id]++; + sh_queue_KBD_EVENT *dev_queue=sh_malloc(sizeof(sh_queue_KBD_EVENT)); + if (!dev_queue) { + kbd_devs.bitmap[id/64]&= ~(1ULL<<(id%64)); + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_ERROR_NULLPTR_RETURNED; + } + SH_STATUS status=sh_queue_event_init(dev_queue,kbd_devs.events_queue_capacity); + if (sh_status_error(status)) { + sh_free(dev_queue); + kbd_devs.bitmap[id/64]&= ~(1ULL<<(id%64)); + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return status; + } + dev->events_queue=dev_queue; + kbd_devs.keyboard_count++; + sh_kbd_DRIVER_HANDLE *driver_handle=sh_malloc(sizeof(sh_kbd_DRIVER_HANDLE)); + if (!dev_queue) { + status=sh_queue_event_destroy(dev_queue); + if (sh_status_error(status)) return status; + sh_free(dev_queue); + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_ERROR_NULLPTR_RETURNED; + } + driver_handle->id=id; + driver_handle->generation=kbd_devs.id_generation[id]; + *handle=driver_handle; + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_kbd_set_flag(sh_kbd_DRIVER_HANDLE *handle,sh_uint8 flag,sh_bool value) { + if (handle==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_spin_lock(&kbd_devs.id_manipulation_spinlock); + if (!kbd_devs.is_kbd_devs_initialized) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_DEVS_NOT_INITIALIZED; + } + sh_uint8 id=handle->id; + if (kbd_devs.id_generation[id]!=handle->generation) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_INVALID_HANDLE; + } + sh_uint32 idx=id/64; + sh_uint32 bit=id%64; + if (!(kbd_devs.bitmap[idx] & (1ULL<spinlock); + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + switch (flag) { + case SH_KBD_FLAG_PRESENT: + dev->present=value; + break; + case SH_KBD_FLAG_VER_MAJ: + dev->ver_maj=value; + break; + case SH_KBD_FLAG_VER_NUM: + dev->ver_num=value; + break; + case SH_KBD_FLAG_SHIFT: + dev->shift=value; + break; + case SH_KBD_FLAG_ALT: + dev->alt=value; + break; + case SH_KBD_FLAG_CTRL: + dev->ctrl=value; + break; + case SH_KBD_FLAG_WIN: + dev->win=value; + break; + default: + sh_spin_unlock(&dev->spinlock); + return SH_STATUS_INVALID_PARAMETER; + } + sh_spin_unlock(&dev->spinlock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_kbd_push_events(sh_kbd_DRIVER_HANDLE *handle,sh_kbd_EVENT *event) { + if (handle==SH_NULLPTR || event==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint8 id=handle->id; + if (kbd_devs.id_generation[id]!=handle->generation) return SH_STATUS_INVALID_HANDLE; + if (!(kbd_devs.bitmap[id/64] & (1ULL<<(id%64)))) return SH_STATUS_INVALID_HANDLE; + sh_kbd_DEVICE *dev=&kbd_devs.by_id[id]; + sh_spin_lock(&dev->spinlock); + if (!dev->present) { + sh_spin_unlock(&dev->spinlock); + return SH_STATUS_DEVICE_NOT_PRESENT; + } + sh_queue_KBD_EVENT *queue=(sh_queue_KBD_EVENT*)dev->events_queue; + if (queue==SH_NULLPTR) { + sh_spin_unlock(&dev->spinlock); + return SH_STATUS_INVALID_STATE; + } + SH_STATUS status=sh_queue_event_push(queue,*event); + if (sh_status_error(status)) { + sh_spin_unlock(&dev->spinlock); + return status; + } + sh_spin_unlock(&dev->spinlock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_kbd_enumerate_devices(sh_kbd_ENUMERATION *enumeration) { + if (enumeration==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_spin_lock(&kbd_devs.id_manipulation_spinlock); + if (!kbd_devs.is_kbd_devs_initialized) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_DEVS_NOT_INITIALIZED; + } + enumeration->bitmap[0]=kbd_devs.bitmap[0]; + enumeration->bitmap[1]=kbd_devs.bitmap[1]; + enumeration->bitmap[2]=kbd_devs.bitmap[2]; + enumeration->bitmap[3]=kbd_devs.bitmap[3]; + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_kbd_get_handle(sh_uint8 kbd_id,sh_kbd_CONSUMER_HANDLE **handle) { + if (handle==SH_NULLPTR)return SH_STATUS_INVALID_PARAMETER; + sh_spin_lock(&kbd_devs.id_manipulation_spinlock); + if (!kbd_devs.is_kbd_devs_initialized) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_DEVS_NOT_INITIALIZED; + } + sh_uint32 idx=kbd_id>>6; + sh_uint32 bit=kbd_id&63; + if (!(kbd_devs.bitmap[idx] & (1ULL<id=kbd_id; + h->generation=generation; + h->read_index=kbd_devs.by_id[kbd_id].events_queue->write_index; + *handle=h; + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_kbd_destroy_handle(sh_kbd_CONSUMER_HANDLE **handle) { + if (handle==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + if (*handle==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_free(*handle); + *handle=SH_NULLPTR; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_kbd_read_flag(sh_kbd_DRIVER_HANDLE *d_handle,sh_kbd_CONSUMER_HANDLE *c_handle,sh_uint8 flag,sh_bool *value) { + if (value==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + if ((d_handle==SH_NULLPTR && c_handle==SH_NULLPTR) || (d_handle!=SH_NULLPTR && c_handle!=SH_NULLPTR)) return SH_STATUS_INVALID_PARAMETER; + sh_uint8 id; + sh_uint32 generation; + if (d_handle!=SH_NULLPTR) { + id=d_handle->id; + generation=d_handle->generation; + } else { + id=c_handle->id; + generation=c_handle->generation; + } + sh_spin_lock(&kbd_devs.id_manipulation_spinlock); + if (!kbd_devs.is_kbd_devs_initialized) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_DEVS_NOT_INITIALIZED; + } + if (kbd_devs.id_generation[id]!=generation) { + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + return SH_STATUS_INVALID_HANDLE; + } + sh_uint32 idx=id>>6; + sh_uint32 bit=id&63; + if (!(kbd_devs.bitmap[idx] & (1ULL<spinlock); + sh_spin_unlock(&kbd_devs.id_manipulation_spinlock); + switch (flag) { + case SH_KBD_FLAG_PRESENT: + *value=dev->present; + break; + case SH_KBD_FLAG_VER_MAJ: + *value=dev->ver_maj; + break; + case SH_KBD_FLAG_VER_NUM: + *value=dev->ver_num; + break; + case SH_KBD_FLAG_SHIFT: + *value=dev->shift; + break; + case SH_KBD_FLAG_ALT: + *value=dev->alt; + break; + case SH_KBD_FLAG_CTRL: + *value=dev->ctrl; + break; + case SH_KBD_FLAG_WIN: + *value=dev->win; + break; + default: + sh_spin_unlock(&dev->spinlock); + return SH_STATUS_INVALID_PARAMETER; + } + sh_spin_unlock(&dev->spinlock); + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/devs/input/ps2.c b/shelter/lib/src/devs/input/ps2.c new file mode 100644 index 0000000..db413d7 --- /dev/null +++ b/shelter/lib/src/devs/input/ps2.c @@ -0,0 +1,777 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "devs/input/ps2.h" +#include "devs/input/kbd.h" +#include "irq/irq.h" +enum ps2_scancode_state { + PS2_SCANCODE_STATE_NORMAL, + PS2_SCANCODE_STATE_E0, + PS2_SCANCODE_STATE_E1 +}; +enum ps2_command_state { + PS2_COMMAND_STATE_IDLE, + PS2_COMMAND_STATE_WAIT_ACK, + PS2_COMMAND_STATE_WAIT_LED_ACK_1, + PS2_COMMAND_STATE_WAIT_LED_ACK_2, + PS2_COMMAND_STATE_WAIT_SC_SET_ACK_1, + PS2_COMMAND_STATE_WAIT_SC_SET_ACK_2, + PS2_COMMAND_STATE_WAIT_IDENTIFY_ACK, + PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_1, + PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_2, + PS2_COMMAND_STATE_WAIT_ECHO, + PS2_COMMAND_STATE_WAIT_RESET_ACK, + PS2_COMMAND_STATE_WAIT_RESET_RESULT +}; +typedef struct { + enum ps2_scancode_state scancode_state; + enum ps2_command_state command_state; + sh_ps2_KBD_COMMAND current_command; + sh_uint8 last_byte; + sh_uint8 e1_bytes_left; + sh_uint8 e1_bytes_idx; + sh_uint8 e1_bytes_array[5]; + sh_bool command_in_progress; + sh_uint8 keyboard_id[2]; + sh_uint8 keyboard_id_len; + sh_bool scanning_enabled; + sh_bool shift_state; + sh_bool l_alt_state; + sh_bool r_alt_state; + sh_bool l_ctrl_state; + sh_bool r_ctrl_state; + sh_bool win_state; + sh_bool capslock_state; + sh_bool numlock_state; + sh_kbd_DRIVER_HANDLE *d_handle; +} ps2_state_template; +ps2_state_template ps2_state; +static void sh_ps2_send_keyboard_command(sh_uint8 cmd,sh_uint8 data,sh_bool has_data) { + ps2_state.current_command.command=cmd; + ps2_state.current_command.data=data; + ps2_state.current_command.has_data=has_data; + ps2_state.command_in_progress=SH_TRUE; + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_DATA,cmd); +} +SH_STATUS sh_ps2_send_keyboard_command_wait(sh_uint8 cmd,sh_uint8 data,sh_bool has_data) { + sh_ps2_send_keyboard_command(cmd,data,has_data); + while (ps2_state.command_in_progress) { + asm volatile("hlt"); + } + return SH_STATUS_SUCCESS; +} +// Because we don't have a scheduler or kernel threads/worker, we can't properly update these leds for the moment +__attribute__((__unused__)) static void sh_ps2_update_leds() { + sh_uint8 led_byte=0; + if (ps2_state.numlock_state) { + led_byte|=SH_PS2_KBD_LEDS_NUM_LOCK; + } + if (ps2_state.capslock_state) { + led_byte|=SH_PS2_KBD_LEDS_CAPS_LOCK; + } + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_LED_ACK_1; + sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_SET_LEDS,led_byte,SH_TRUE); + return; +} +static SH_STATUS sh_ps2_handle_command_response(sh_uint8 data) { + if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_ACK) { + if (data==SH_PS2_KBD_ACK) { + if (ps2_state.current_command.command==SH_PS2_KBD_COMMAND_DISABLE_SCANNING) { + ps2_state.scanning_enabled=SH_FALSE; + } else if (ps2_state.current_command.command==SH_PS2_KBD_COMMAND_ENABLE_SCANNING) { + ps2_state.scanning_enabled=SH_TRUE; + } + ps2_state.command_state=PS2_COMMAND_STATE_IDLE; + ps2_state.current_command.command=0; + ps2_state.current_command.data=0; + ps2_state.current_command.has_data=SH_FALSE; + ps2_state.command_in_progress=SH_FALSE; + return SH_STATUS_SUCCESS; + } else if (data==SH_PS2_KBD_RESEND) { + sh_ps2_send_keyboard_command(ps2_state.current_command.command,ps2_state.current_command.data,ps2_state.current_command.has_data); + return SH_STATUS_SUCCESS; + } + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_ECHO) { + if (data==SH_PS2_KBD_COMMAND_ECHO) { + ps2_state.command_state=PS2_COMMAND_STATE_IDLE; + ps2_state.command_in_progress=SH_FALSE; + return SH_STATUS_SUCCESS; + } else { + sh_iprint(SH_DEBUG,"wrong echo\n"); + return SH_STATUS_SUCCESS; + } + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_IDENTIFY_ACK) { + if (data==SH_PS2_KBD_ACK) { + ps2_state.keyboard_id_len=0; + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_1; + return SH_STATUS_SUCCESS; + } else if (data==SH_PS2_KBD_RESEND) { + sh_ps2_send_keyboard_command(SH_PS2_KBD_COMMAND_IDENTIFY,0,SH_FALSE); + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_IDENTIFY_ACK; + return SH_STATUS_SUCCESS; + } + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_1) { + ps2_state.keyboard_id[0]=data; + ps2_state.keyboard_id_len=1; + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_2; + return SH_STATUS_SUCCESS; + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_IDENTIFY_BYTE_2) { + ps2_state.keyboard_id[1]=data; + ps2_state.keyboard_id_len=2; + ps2_state.command_state=PS2_COMMAND_STATE_IDLE; + ps2_state.command_in_progress=SH_FALSE; + return SH_STATUS_SUCCESS; + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_LED_ACK_1) { + if (data==SH_PS2_KBD_ACK) { + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_DATA,ps2_state.current_command.data); + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_LED_ACK_2; + return SH_STATUS_SUCCESS; + } else if (data==SH_PS2_KBD_RESEND) { + sh_ps2_send_keyboard_command(SH_PS2_KBD_COMMAND_SET_LEDS,ps2_state.current_command.data,SH_TRUE); + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_LED_ACK_1; + return SH_STATUS_SUCCESS; + } + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_LED_ACK_2) { + if (data==SH_PS2_KBD_ACK) { + ps2_state.command_state=PS2_COMMAND_STATE_IDLE; + ps2_state.command_in_progress=SH_FALSE; + return SH_STATUS_SUCCESS; + } else if (data==SH_PS2_KBD_RESEND) { + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_DATA,ps2_state.current_command.data); + return SH_STATUS_SUCCESS; + } + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_RESET_ACK) { + if (data==SH_PS2_KBD_ACK) { + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_RESET_RESULT; + return SH_STATUS_SUCCESS; + } else if (data==SH_PS2_KBD_RESEND) { + sh_ps2_send_keyboard_command(SH_PS2_KBD_COMMAND_RESET,0,SH_FALSE); + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_RESET_ACK; + return SH_STATUS_SUCCESS; + } + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_RESET_RESULT) { + if (data==0xAA || data==0xFC) { + ps2_state.command_state=PS2_COMMAND_STATE_IDLE; + ps2_state.command_in_progress=SH_FALSE; + return SH_STATUS_SUCCESS; + } else { + sh_iprintf(SH_DEBUG,"wrong reset\n"); + } + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_SC_SET_ACK_1) { + if (data==SH_PS2_KBD_ACK) { + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_DATA,ps2_state.current_command.data); + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_SC_SET_ACK_2; + return SH_STATUS_SUCCESS; + } else if (data==SH_PS2_KBD_RESEND) { + sh_ps2_send_keyboard_command(SH_PS2_KBD_COMMAND_SC_SET,ps2_state.current_command.data,SH_TRUE); + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_SC_SET_ACK_1; + return SH_STATUS_SUCCESS; + } + } else if (ps2_state.command_state==PS2_COMMAND_STATE_WAIT_SC_SET_ACK_2) { + if (data==SH_PS2_KBD_ACK) { + ps2_state.command_state=PS2_COMMAND_STATE_IDLE; + ps2_state.command_in_progress=SH_FALSE; + return SH_STATUS_SUCCESS; + } else if (data==SH_PS2_KBD_RESEND) { + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_DATA,ps2_state.current_command.data); + return SH_STATUS_SUCCESS; + } + } + return SH_STATUS_INVALID_STATE; +} +static inline sh_bool sh_ps2_shift() { + return ps2_state.shift_state; +} +static inline sh_bool sh_ps2_alt() { + return ps2_state.l_alt_state || ps2_state.r_alt_state; +} +static inline sh_bool sh_ps2_ctrl() { + return ps2_state.l_ctrl_state || ps2_state.r_ctrl_state; +} +static void sh_ps2_handle_scancodes(sh_uint8 data) { + if (data==0xE0 && ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) { + ps2_state.scancode_state=PS2_SCANCODE_STATE_E0; + return; + } else if (data==0xE1 && ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) { + ps2_state.scancode_state=PS2_SCANCODE_STATE_E1; + ps2_state.e1_bytes_left=5; + ps2_state.e1_bytes_idx=0; + return; + } + if (ps2_state.scancode_state!=PS2_SCANCODE_STATE_E1) { + switch (data) { + case 0x1D: { + // ctrl pressed + if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) { + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_LCTRL, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.l_ctrl_state=SH_TRUE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_CTRL,sh_ps2_ctrl()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings ctrl flags: status=%8s\n",status); + } + return; + } else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) { + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_RCTRL, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.r_ctrl_state=SH_TRUE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_CTRL,sh_ps2_ctrl()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings ctrl flags: status=%8s\n",status); + } + ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL; + return; + } + break; + } + case 0x9D: { + // ctrl released + if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) { + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_LCTRL, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.l_ctrl_state=SH_FALSE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_CTRL,sh_ps2_ctrl()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings ctrl flags: status=%8s\n",status); + } + return; + } else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) { + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_RCTRL, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.r_ctrl_state=SH_FALSE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_CTRL,sh_ps2_ctrl()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings ctrl flags: status=%8s\n",status); + } + ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL; + return; + } + break; + } + case 0x36: { + // right shift pressed + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_RSHIFT, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.shift_state=SH_TRUE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_SHIFT,sh_ps2_shift()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings shift flags: status=%8s\n",status); + } + return; + } + case 0x2A: { + // left shift pressed + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_LSHIFT, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.shift_state=SH_TRUE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_SHIFT,sh_ps2_shift()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings shift flags: status=%8s\n",status); + } + return; + } + case 0xAA: { + // left shift released + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_LSHIFT, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.shift_state=SH_FALSE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_SHIFT,sh_ps2_shift()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings shift flags: status=%8s\n",status); + } + return; + } + case 0xB6: { + // right shift released + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_RSHIFT, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.shift_state=SH_FALSE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_SHIFT,sh_ps2_shift()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings shift flags: status=%8s\n",status); + } + return; + } + case 0x38: { + // alt pressed + if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) { + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_LALT, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.l_alt_state=SH_TRUE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_ALT,sh_ps2_alt()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings alt flags: status=%8s\n",status); + } + return; + } else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) { + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_RALT, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.r_alt_state=SH_TRUE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_ALT,sh_ps2_alt()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings alt flags: status=%8s\n",status); + } + ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL; + return; + } + break; + } + case 0xB8: { + // alt released + if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) { + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_LALT, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.l_alt_state=SH_FALSE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_ALT,sh_ps2_alt()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings alt flags: status=%8s\n",status); + } + return; + } else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) { + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_RALT, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.r_alt_state=SH_FALSE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_ALT,sh_ps2_alt()); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings alt flags: status=%8s\n",status); + } + ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL; + return; + } + break; + } + case 0xC5: { + // numlock released + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_NUMLOCK, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.numlock_state=ps2_state.numlock_state?SH_FALSE:SH_TRUE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_VER_NUM,ps2_state.numlock_state); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings numlock flags: status=%8s\n",status); + } + return; + } + case 0xBA: { + // capslock released + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_CAPSLOCK, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + ps2_state.capslock_state=ps2_state.capslock_state?SH_FALSE:SH_TRUE; + status=sh_kbd_set_flag(ps2_state.d_handle,SH_KBD_FLAG_VER_MAJ,ps2_state.capslock_state); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error settings capslock flags: status=%8s\n",status); + } + return; + } + case 0x45: { + // numlock pressed + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_NUMLOCK, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + return; + } + case 0x3A: { + // capslock pressed + sh_kbd_EVENT ev={ + .scancode=SH_KBD_CONTEXT_CAPSLOCK, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_CONTEXT, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + return; + } + default: { + break; + } + } + } + if (ps2_state.scancode_state==PS2_SCANCODE_STATE_NORMAL) { + if (data & (1u<<7)) { + sh_kbd_EVENT ev={ + .scancode=0x0000|data, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_PS2_NORMAL, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + return; + } else { + sh_kbd_EVENT ev={ + .scancode=0x0000|data, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_PS2_NORMAL, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + return; + } + } else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E0) { + if (data & (1u<<7)) { + sh_kbd_EVENT ev={ + .scancode=0xE000|data, + .pressed=SH_FALSE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_PS2_E0, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + return; + } else { + sh_kbd_EVENT ev={ + .scancode=0xE000|data, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_PS2_E0, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + return; + } + } else if (ps2_state.scancode_state==PS2_SCANCODE_STATE_E1) { + ps2_state.e1_bytes_array[ps2_state.e1_bytes_idx]=data; + ps2_state.e1_bytes_left--; + ps2_state.e1_bytes_idx++; + if (ps2_state.e1_bytes_idx==5 && ps2_state.e1_bytes_left==0) ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL; + sh_kbd_EVENT ev={ + .scancode=0, + .pressed=SH_TRUE, + .context_shift_win=(ps2_state.win_state<<1)|(sh_ps2_shift()), + .context_alt=(ps2_state.l_alt_state<<1)|(ps2_state.r_alt_state), + .context_ctrl=(ps2_state.l_ctrl_state<<1)|(ps2_state.r_ctrl_state), + .context_lock_status=(ps2_state.capslock_state<<1)|(ps2_state.numlock_state), + .event_type=SH_EVENT_TYPE_KBD_PAUSE, + .timestamp=sh_tsc_get_kernel_current_tsc() + }; + SH_STATUS status=sh_kbd_push_events(ps2_state.d_handle,&ev); + if (sh_status_error(status)) { + sh_iprintf(SH_WARNING,"Error pushing events: status=%8s\n",status); + } + return; + } +} +void sh_ps2_irq1_handler() { + sh_uint8 data; + if (!sh_ps2_output_ready()) return; + data=sh_asm_inb(SH_PS2_PORT_DATA); + ps2_state.last_byte=data; + if (ps2_state.command_in_progress) { + sh_ps2_handle_command_response(data); + return; + } + if (ps2_state.scanning_enabled) { + sh_ps2_handle_scancodes(data); + } + return; +} +SH_STATUS sh_ps2_driver_init() { + sh_asm_cli(); + // flush output buffer + while (sh_ps2_output_ready()) { + sh_asm_inb(SH_PS2_PORT_DATA); + } + // debug log status and config byte + sh_printf(SH_DEBUG,"PS2 status byte initial value: 0x%1U\n",sh_ps2_read_status()); + sh_printf(SH_DEBUG,"PS2 config byte initial value: 0x%1U\n",sh_ps2_read_config()); + // disable ps2 ports + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PORT1_DISABLE); + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PORT2_DISABLE); + // reflush output buffer + while (sh_ps2_output_ready()) { + sh_asm_inb(SH_PS2_PORT_DATA); + } + // disable IRQs + sh_uint8 cfg=sh_ps2_read_config(); + cfg&= (sh_uint8)~SH_PS2_CONFIG_PORT1_IRQ; + cfg&= (sh_uint8)~SH_PS2_CONFIG_PORT2_IRQ; + sh_ps2_write_config(cfg); + // ps2 self test + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PS2_SELF_TEST); + while (!sh_ps2_output_ready()); + sh_uint8 result=sh_asm_inb(SH_PS2_PORT_DATA); + if (result!=SH_PS2_SELF_TEST_SUCCESS) return SH_STATUS_TEST_FAILED; + // port1 test + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PORT1_TEST); + while (!sh_ps2_output_ready()); + result=sh_asm_inb(SH_PS2_PORT_DATA); + if (result!=SH_PS2_PORTS_SELF_TEST_SUCCESS) return SH_STATUS_TEST_FAILED; + // enable port1 + while (sh_ps2_cant_write()); + sh_asm_outb(SH_PS2_PORT_COMMAND,SH_PS2_COMMAND_PORT1_ENABLE); + // enable translation + cfg=sh_ps2_read_config(); + cfg|=SH_PS2_CONFIG_TRANSLATION; + sh_ps2_write_config(cfg); + // initialize ps2_state struct + ps2_state.scancode_state=PS2_SCANCODE_STATE_NORMAL; + ps2_state.command_state=PS2_COMMAND_STATE_IDLE; + ps2_state.current_command.command=0; + ps2_state.current_command.data=0; + ps2_state.current_command.has_data=SH_FALSE; + ps2_state.last_byte=0; + ps2_state.e1_bytes_left=0; + ps2_state.command_in_progress=SH_FALSE; + ps2_state.keyboard_id[0]=0; + ps2_state.keyboard_id[1]=0; + ps2_state.keyboard_id_len=0; + ps2_state.shift_state=SH_FALSE; + ps2_state.l_alt_state=SH_FALSE; + ps2_state.r_alt_state=SH_FALSE; + ps2_state.l_ctrl_state=SH_FALSE; + ps2_state.r_ctrl_state=SH_FALSE; + ps2_state.win_state=SH_FALSE; + ps2_state.capslock_state=SH_FALSE; + ps2_state.numlock_state=SH_FALSE; + // enabling IRQ1 + cfg=sh_ps2_read_config(); + cfg|=(sh_uint8)SH_PS2_CONFIG_PORT1_IRQ; + sh_ps2_write_config(cfg); + SH_STATUS status=sh_irq_legacy_register_handler(1,&sh_ps2_irq1_handler); + if (sh_status_error(status)) return status; + sh_asm_sti(); + // disabling scanning + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_ACK; + sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_DISABLE_SCANNING,0,SH_FALSE); + // set leds + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_LED_ACK_1; + sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_SET_LEDS,0,SH_TRUE); + // identify keyboard + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_IDENTIFY_ACK; + sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_IDENTIFY,0,SH_FALSE); + sh_printf(SH_DEBUG,"PS2 identifier value : 0x%1U 0x%1U\n",ps2_state.keyboard_id[0],ps2_state.keyboard_id[1]); + // register ps2 keyboard + status=sh_kbd_register_ps2(SH_TRUE,&ps2_state.d_handle); + if (sh_status_error(status)) return status; + // enable scanning + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_ACK; + sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_ENABLE_SCANNING,0,SH_FALSE); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_ps2_disable_scanning() { + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_ACK; + sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_DISABLE_SCANNING,0,SH_FALSE); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_ps2_enable_scanning() { + ps2_state.command_state=PS2_COMMAND_STATE_WAIT_ACK; + sh_ps2_send_keyboard_command_wait(SH_PS2_KBD_COMMAND_ENABLE_SCANNING,0,SH_FALSE); + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/irq/gdt.c b/shelter/lib/src/irq/gdt.c new file mode 100644 index 0000000..eae04e8 --- /dev/null +++ b/shelter/lib/src/irq/gdt.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "irq/gdt.h" +#include "cpu/asm.h" +sh_gdt_GDT_ENTRY_64 sh_gdt_fill_gdt_entry_64(sh_uint32 limit,sh_uint32 base,sh_uint8 access,sh_uint8 flags) { + sh_gdt_GDT_ENTRY_64 entry; + entry.limit_low=(sh_uint16)(limit & 0xFFFF); + entry.base_low=(sh_uint16)(base & 0xFFFF); + entry.base_mid=(sh_uint8)((base>>16)&0xFF); + entry.access=access; + entry.flags_limit_high=(sh_uint8)(((flags&0xF)<<4)|((limit>>16)&0xF)); + entry.base_high=(sh_uint8)((base>>24)&0xFF); + return entry; +} +sh_gdt_GDT_ENTRY_128 sh_gdt_fill_gdt_entry_128(sh_uint32 limit,sh_uint64 base,sh_uint8 access,sh_uint8 flags) { + sh_gdt_GDT_ENTRY_128 entry; + entry.limit_low=(sh_uint16)(limit&0xFFFF); + entry.base_low=(sh_uint16)(base&0xFFFF); + entry.base_mid=(sh_uint8)((base>>16)&0xFF); + entry.access=access; + entry.flags_limit_high=(sh_uint8)(((flags&0xF)<<4)|((limit>>16)&0xF)); + entry.base_high=(sh_uint8)((base>>24)&0xFF); + entry.base_upper=(sh_uint32)((base>>32)&0xFFFFFFFF); + entry.reserved=0; + return entry; +} +SH_STATUS sh_gdt_fill_gdt(sh_tss_TSS *tss,sh_gdt_GDT *gdt) { + if (tss==SH_NULLPTR || gdt==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_mem_set_8((sh_uint8 *)gdt,0x0,sizeof(sh_gdt_GDT)); + gdt->null=sh_gdt_fill_gdt_entry_64(0,0,0,0); + gdt->kernel_code=sh_gdt_fill_gdt_entry_64(0,0,sh_gdt_fill_access_byte(SH_TRUE,0,SH_TRUE,0xA),sh_gdt_fill_flags_byte(SH_FALSE,SH_FALSE,SH_TRUE,SH_FALSE)); + gdt->kernel_data=sh_gdt_fill_gdt_entry_64(0,0,sh_gdt_fill_access_byte(SH_TRUE,0,SH_TRUE,0x2),sh_gdt_fill_flags_byte(SH_FALSE,SH_FALSE,SH_FALSE,SH_FALSE)); + gdt->user_code=sh_gdt_fill_gdt_entry_64(0,0,sh_gdt_fill_access_byte(SH_TRUE,3,SH_TRUE,0xA),sh_gdt_fill_flags_byte(SH_FALSE,SH_FALSE,SH_TRUE,SH_FALSE)); + gdt->user_data=sh_gdt_fill_gdt_entry_64(0,0,sh_gdt_fill_access_byte(SH_TRUE,3,SH_TRUE,0x2),sh_gdt_fill_flags_byte(SH_FALSE,SH_FALSE,SH_FALSE,SH_FALSE)); + gdt->tss=sh_gdt_fill_gdt_entry_128(sizeof(sh_tss_TSS)-1,(sh_uint64)tss,sh_gdt_fill_access_byte(SH_TRUE,0,SH_FALSE,0x9),0); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_gdt_fill_gdt_ap(sh_tss_TSS *tss,sh_uint64 tss_count,sh_gdt_GDT_AP *gdt) { + if (tss==SH_NULLPTR || tss_count==0 || tss_count>256 || gdt==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_mem_set_8((sh_uint8 *)gdt,0x0,sizeof(sh_gdt_GDT)); + gdt->null=sh_gdt_fill_gdt_entry_64(0,0,0,0); + gdt->kernel_code=sh_gdt_fill_gdt_entry_64(0,0,sh_gdt_fill_access_byte(SH_TRUE,0,SH_TRUE,0xA),sh_gdt_fill_flags_byte(SH_FALSE,SH_FALSE,SH_TRUE,SH_FALSE)); + gdt->kernel_data=sh_gdt_fill_gdt_entry_64(0,0,sh_gdt_fill_access_byte(SH_TRUE,0,SH_TRUE,0x2),sh_gdt_fill_flags_byte(SH_FALSE,SH_FALSE,SH_FALSE,SH_FALSE)); + gdt->user_code=sh_gdt_fill_gdt_entry_64(0,0,sh_gdt_fill_access_byte(SH_TRUE,3,SH_TRUE,0xA),sh_gdt_fill_flags_byte(SH_FALSE,SH_FALSE,SH_TRUE,SH_FALSE)); + gdt->user_data=sh_gdt_fill_gdt_entry_64(0,0,sh_gdt_fill_access_byte(SH_TRUE,3,SH_TRUE,0x2),sh_gdt_fill_flags_byte(SH_FALSE,SH_FALSE,SH_FALSE,SH_FALSE)); + for (sh_iter64 i=0;itss[i]=sh_gdt_fill_gdt_entry_128(sizeof(sh_tss_TSS)-1,(sh_uint64)&tss[i],sh_gdt_fill_access_byte(SH_TRUE,0,SH_FALSE,0x9),0); + } + return SH_STATUS_SUCCESS; +} +sh_gdt_GDTR sh_gdt_make_gdtr_ap(sh_gdt_GDT_AP *gdt) { + if (gdt==SH_NULLPTR) return (sh_gdt_GDTR){0}; + sh_gdt_GDTR gdtr; + gdtr.limit=(sh_uint16)(sizeof(sh_gdt_GDT_AP)-1); + gdtr.base=(sh_uint64)gdt; + return gdtr; +} +SH_STATUS sh_gdt_load_gdtr(sh_gdt_GDT *gdt) { + if (gdt==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_gdt_GDTR gdtr; + gdtr.limit=(sh_uint16)(sizeof(sh_gdt_GDT)-1); + gdtr.base=(sh_uint64)gdt; + sh_asm_lgdt(gdtr); + return SH_STATUS_SUCCESS; +} +extern SH_STATUS sh_gdt_reload_registers(); +sh_gdt_GDT_ENTRY_32 sh_gdt_fill_gdt_entry_32(sh_uint32 limit,sh_uint32 base,sh_uint8 access,sh_uint8 granularity) { + sh_gdt_GDT_ENTRY_32 entry; + entry.limit_low=limit&0xFFFF; + entry.base_low=base&0xFFFF; + entry.base_middle=(base>>16)&0xFF; + entry.base_high=(sh_uint8)(base>>24)&0xFF; + entry.access=access; + entry.granularity=(granularity&0xF0)|((limit>>16)&0x0F); + return entry; +} +SH_STATUS sh_gdt_fill_gdt_32(sh_gdt_GDT_32 *gdt_32){ + if (!gdt_32) return SH_STATUS_INVALID_PARAMETER; + gdt_32->null=(sh_gdt_GDT_ENTRY_32){0}; + gdt_32->code=sh_gdt_fill_gdt_entry_32(0xFFFFF,0x00000000,sh_gdt_fill_access_byte_32(SH_TRUE,0,SH_TRUE,0xA),sh_gdt_fill_granularity_byte_32(SH_TRUE,SH_TRUE,SH_FALSE,SH_FALSE)); + gdt_32->data=sh_gdt_fill_gdt_entry_32(0xFFFFF,0x00000000,sh_gdt_fill_access_byte_32(SH_TRUE,0,SH_TRUE,0x2),sh_gdt_fill_granularity_byte_32(SH_TRUE,SH_TRUE,SH_FALSE,SH_FALSE)); + gdt_32->code_64=sh_gdt_fill_gdt_entry_32(0xFFFFF,0x00000000,sh_gdt_fill_access_byte_32(SH_TRUE,0,SH_TRUE,0xA),sh_gdt_fill_granularity_byte_32(SH_TRUE,SH_FALSE,SH_TRUE,SH_FALSE)); + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/irq/gdt_reload.asm b/shelter/lib/src/irq/gdt_reload.asm new file mode 100644 index 0000000..390666d --- /dev/null +++ b/shelter/lib/src/irq/gdt_reload.asm @@ -0,0 +1,21 @@ +; SPDX-License-Identifier: MPL-2.0 +global sh_gdt_reload_registers + +section .text + +sh_gdt_reload_registers: + mov ax, 0x10 + mov ds, ax + mov es, ax + mov ss, ax + xor ax, ax + mov fs, ax + mov gs, ax + + push 0x08 + lea rax, [rel .reload] + push rax + retfq + +.reload: + ret diff --git a/shelter/lib/src/irq/gsi.c b/shelter/lib/src/irq/gsi.c new file mode 100644 index 0000000..e27deb1 --- /dev/null +++ b/shelter/lib/src/irq/gsi.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "irq/gsi.h" +#include "irq/irq.h" +static sh_gsi_ISO *iso_array=SH_NULLPTR; +sh_uint16 bumb=0; +SH_STATUS sh_gsi_iso_array_init() { + iso_array=sh_malloc(sizeof(sh_gsi_ISO)*256); + if (!iso_array) return SH_STATUS_ERROR_NULLPTR_RETURNED; + bumb=0; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_gsi_iso_register(sh_uint8 bus,sh_uint8 source,sh_uint32 gsi,sh_uint16 flags) { + if (!iso_array) return SH_STATUS_UNAVAILABLE; + if (bumb>=256) return SH_STATUS_TOO_MUCH_DATA; + for (sh_uint16 i=0;ibus=bus; + iso->source_irq=source; + iso->gsi=gsi; + iso->valid=SH_TRUE; + switch (flags & 0x3) { + case 0: + iso->polarity=SH_GSI_POLARITY_BUS_DEFAULT; + break; + case 1: + iso->polarity=SH_GSI_POLARITY_ACTIVE_HIGH; + break; + case 3: + iso->polarity=SH_GSI_POLARITY_ACTIVE_LOW; + break; + default: + iso->polarity=SH_GSI_POLARITY_BUS_DEFAULT; + break; + } + switch (flags & 0xC) { + case 0: + iso->trigger_mode=SH_GSI_TRIGGER_MODE_BUS_DEFAULT; + break; + case 0x4: + iso->trigger_mode=SH_GSI_TRIGGER_MODE_EDGE; + break; + case 0xC: + iso->trigger_mode=SH_GSI_TRIGGER_MODE_LEVEL; + break; + default: + iso->trigger_mode=SH_GSI_TRIGGER_MODE_BUS_DEFAULT; + break; + } + return SH_STATUS_SUCCESS; +} +sh_gsi_ISO *sh_gsi_get_iso_by_irq(sh_uint8 irq) { + if (!iso_array) return SH_NULLPTR; + for (sh_uint16 i=0;ivalid) { + gsi=iso->gsi; + } + return sh_gsi_set(gsi,entry); +} +SH_STATUS sh_gsi_irq_mask(sh_uint8 irq) { + sh_uint32 gsi=irq; + sh_gsi_ISO *iso=sh_gsi_get_iso_by_irq(irq); + if (iso && iso->valid) { + gsi=iso->gsi; + } + return sh_gsi_mask(gsi); +} +SH_STATUS sh_gsi_irq_unmask(sh_uint8 irq) { + sh_uint32 gsi=irq; + sh_gsi_ISO *iso=sh_gsi_get_iso_by_irq(irq); + if (iso && iso->valid) { + gsi=iso->gsi; + } + return sh_gsi_unmask(gsi); +} +SH_STATUS sh_gsi_irq_switch() { + sh_bool gsi_already_used[256]={0}; + for (sh_iter64 i=0;i<16;i++) { + sh_ioapic_IOREDTBL_ENTRY entry={0}; + sh_gsi_ISO *iso=sh_gsi_get_iso_by_irq((sh_uint8)i); + sh_uint32 gsi=(sh_uint32)i; + sh_uint8 polarity=SH_IOAPIC_IOREDTBL_POLARITY_HIGH; + sh_uint8 trigger_mode=SH_IOAPIC_IOREDTBL_TRIGGER_EDGE; + if (iso && iso->valid) { + gsi=iso->gsi; + if (iso->polarity==SH_GSI_POLARITY_ACTIVE_LOW) { + polarity=SH_IOAPIC_IOREDTBL_POLARITY_LOW; + } else if (iso->polarity==SH_GSI_POLARITY_BUS_DEFAULT) { + if (iso->bus==0) { + polarity=SH_IOAPIC_IOREDTBL_POLARITY_HIGH; + } else { + return SH_STATUS_ISO_UNKNOW_BUS; + } + } + if (iso->trigger_mode==SH_GSI_TRIGGER_MODE_LEVEL) { + trigger_mode=SH_IOAPIC_IOREDTBL_TRIGGER_LEVEL; + } else if (iso->trigger_mode==SH_GSI_TRIGGER_MODE_BUS_DEFAULT) { + if (iso->bus==0) { + trigger_mode=SH_IOAPIC_IOREDTBL_TRIGGER_EDGE; + } else { + return SH_STATUS_ISO_UNKNOW_BUS; + } + } + } + if (gsi_already_used[gsi]) continue; + entry=sh_ioapic_make_ioredtbl_entry((sh_uint8)i+32,SH_IOAPIC_IOREDTBL_DELIVERY_FIXED,SH_IOAPIC_IOREDTBL_DEST_MODE_PHYSICAL,polarity,trigger_mode,SH_TRUE,0); + SH_STATUS status=sh_gsi_irq_set((sh_uint8)i,&entry); + if (sh_status_error(status)) return status; + gsi_already_used[gsi]=SH_TRUE; + sh_gsi_irq_mask((sh_uint8)i); + } + SH_STATUS status=sh_irq_switch_irq_management(); + if (sh_status_error(status)) return status; + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/irq/idt.c b/shelter/lib/src/irq/idt.c new file mode 100644 index 0000000..faea311 --- /dev/null +++ b/shelter/lib/src/irq/idt.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "irq/idt.h" +#include "cpu/asm.h" +sh_idt_IDT_ENTRY sh_idt_fill_idt_entry(sh_uint64 offset,sh_uint16 selector,sh_uint8 ist,sh_uint8 type_attr) { + sh_idt_IDT_ENTRY entry; + entry.offset_low=(sh_uint16)(offset&0xFFFF); + entry.selector=selector; + entry.ist=(sh_uint8)(ist&0x7); + entry.type_attr=type_attr; + entry.offset_mid=(sh_uint16)((offset>>16)&0xFFFF); + entry.offset_high=(sh_uint32)((offset>>32)&0xFFFFFFFF); + entry.reserved=0; + return entry; +} +extern void sh_irq_noerr_0(void); +extern void sh_irq_noerr_1(void); +extern void sh_irq_noerr_2(void); +extern void sh_irq_noerr_3(void); +extern void sh_irq_noerr_4(void); +extern void sh_irq_noerr_5(void); +extern void sh_irq_noerr_6(void); +extern void sh_irq_noerr_7(void); +extern void sh_irq_err_8(void); +extern void sh_irq_noerr_9(void); +extern void sh_irq_err_10(void); +extern void sh_irq_err_11(void); +extern void sh_irq_err_12(void); +extern void sh_irq_err_13(void); +extern void sh_irq_err_14(void); +extern void sh_irq_noerr_16(void); +extern void sh_irq_err_17(void); +extern void sh_irq_noerr_18(void); +extern void sh_irq_noerr_19(void); +extern void sh_irq_noerr_20(void); +extern void sh_irq_err_21(void); +extern void sh_irq_noerr_28(void); +extern void sh_irq_err_29(void); +extern void sh_irq_err_30(void); +extern void sh_irq_noerr_32(void); +extern void sh_irq_noerr_33(void); +extern void sh_irq_noerr_34(void); +extern void sh_irq_noerr_35(void); +extern void sh_irq_noerr_36(void); +extern void sh_irq_noerr_37(void); +extern void sh_irq_noerr_38(void); +extern void sh_irq_noerr_39(void); +extern void sh_irq_noerr_40(void); +extern void sh_irq_noerr_41(void); +extern void sh_irq_noerr_42(void); +extern void sh_irq_noerr_43(void); +extern void sh_irq_noerr_44(void); +extern void sh_irq_noerr_45(void); +extern void sh_irq_noerr_46(void); +extern void sh_irq_noerr_47(void); +extern void sh_irq_noerr_254(void); +extern void sh_irq_noerr_255(void); +SH_STATUS sh_idt_fill_idt(sh_idt_IDT *idt) { + idt->entries[0]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_0,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[1]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_1,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[2]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_2,0x08,2,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[3]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_3,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xF)); + idt->entries[4]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_4,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xF)); + idt->entries[5]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_5,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[6]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_6,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[7]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_7,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[8]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_8,0x08,1,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[9]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_9,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[10]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_10,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[11]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_11,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[12]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_12,0x08,4,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[13]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_13,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[14]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_14,0x08,3,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[16]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_16,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[17]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_17,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[18]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_18,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[19]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_19,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[20]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_20,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[21]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_21,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[28]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_28,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[29]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_29,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[30]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_err_30,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[32]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_32,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[33]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_33,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[34]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_34,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[35]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_35,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[36]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_36,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[37]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_37,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[38]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_38,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[39]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_39,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[40]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_40,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[41]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_41,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[42]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_42,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[43]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_43,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[44]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_44,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[45]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_45,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[46]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_46,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[47]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_47,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[254]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_254,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + idt->entries[255]=sh_idt_fill_idt_entry((sh_uint64)sh_irq_noerr_255,0x08,0,sh_idt_fill_type_attr_byte(SH_TRUE,0,0xE)); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_idt_load_idtr(sh_idt_IDT *idt) { + if (idt==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_idt_IDTR idtr; + idtr.limit=(sh_uint16)(sizeof(sh_idt_IDT)-1); + idtr.base=(sh_uint64)idt; + sh_asm_lidt(idtr); + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/irq/irq.c b/shelter/lib/src/irq/irq.c new file mode 100644 index 0000000..4d3cec3 --- /dev/null +++ b/shelter/lib/src/irq/irq.c @@ -0,0 +1,243 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "std/stdlib.h" +#include "irq/irq.h" +#include "irq/gsi.h" +#include "devs/apic/lapic.h" +#include "cpu/pic.h" +sh_uint64 tsc_delta; +sh_uint64 tsc_start; +sh_uint64 tsc_end; +sh_uint8 tsc_state=2; +sh_bool irq_managed_by_ioapic=SH_FALSE; +sh_irq_HANDLER_PTR *legacy_irq_handler_array; +sh_SPIN_LOCK frame_presentation_lock=SH_LOCK(); +void sh_irq_start_tsc() { + tsc_delta=0; + tsc_start=0; + tsc_end=0; + tsc_state=0; +} +sh_uint64 sh_irq_get_tsc_delta() { + return tsc_delta; +} +void sh_irq_start_timer() { + sh_smp_gs_base()->per_cpu->timer_state=SH_TRUE; + return; +} +sh_bool sh_irq_get_timer_state() { + return sh_smp_gs_base()->per_cpu->timer_state; +} +SH_STATUS sh_irq_switch_irq_management() { + if (irq_managed_by_ioapic) return SH_STATUS_ALREADY_INITIALIZED; + irq_managed_by_ioapic=SH_TRUE; + legacy_irq_handler_array=sh_malloc(sizeof(sh_irq_HANDLER_PTR)*16); + if (!legacy_irq_handler_array) return SH_STATUS_ERROR_NULLPTR_RETURNED; + sh_mem_set_8((sh_uint8*)legacy_irq_handler_array,0x0,sizeof(sh_irq_HANDLER_PTR)*16); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_irq_legacy_register_handler(sh_uint8 legacy_irq,sh_irq_HANDLER_PTR handler) { + if (legacy_irq>15 || handler==SH_NULLPTR || legacy_irq==0) return SH_STATUS_INVALID_PARAMETER; + if (legacy_irq_handler_array==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + if (legacy_irq_handler_array[legacy_irq]!=SH_NULLPTR) return SH_STATUS_ALREADY_INITIALIZED; + legacy_irq_handler_array[legacy_irq]=handler; + SH_STATUS status=sh_gsi_irq_unmask(legacy_irq); + if (sh_status_error(status)) return status; + return SH_STATUS_SUCCESS; +} +void sh_irq_present_frame(sh_irq_INTERRUPT_FRAME *frame) { + sh_spin_lock(&frame_presentation_lock); + if (frame->error_code) { + sh_iprintf(SH_FAULT,"IDT Entry Index (vector): %8u | Error code: %8u\n",frame->vector,frame->error_code); + } else { + sh_iprintf(SH_FAULT,"IDT Entry Index (vector): %8u | No error code provided.\n",frame->vector); + } + sh_iprintf(SH_FAULT,"RIP: 0x%x | R8 : 0x%x\n",frame->rip,frame->r8); + sh_iprintf(SH_FAULT,"RAX: 0x%x | R9 : 0x%x\n",frame->rax,frame->r9); + sh_iprintf(SH_FAULT,"RCX: 0x%x | R10: 0x%x\n",frame->rcx,frame->r10); + sh_iprintf(SH_FAULT,"RDX: 0x%x | R11: 0x%x\n",frame->rdx,frame->r11); + sh_iprintf(SH_FAULT,"CS : 0x%x | RFLAGS: 0x%x\n",frame->cs,frame->rflags); + sh_spin_unlock(&frame_presentation_lock); + return; +} +void sh_irq_dispatch(sh_irq_INTERRUPT_FRAME *frame) { + switch (frame->vector) { + case 0: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_DIV_BY_ZERO_FAULT_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 1: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_DEBUG_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 2: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_NMI_FAULT_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 3: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_BREAKPOINT_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + // usage of breakpoints is authorized + break; + case 4: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_OVERFLOW_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 5: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_BOUND_RANGE_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 6: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_INVALID_OPCODE_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 7: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_DEVICE_NOT_AVAILABLE_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 8: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_DOUBLE_FAULT_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 9: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_COPROCESSOR_SEGMENT_OVRERRUN_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 10: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_INVALID_TSS_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 11: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_SEGMENT_NOT_PRESENT_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 12: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_STACK_SEGMENT_FAULT_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 13: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_GENERAL_PROTECTION_FAULT_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 14: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_PAGE_FAULT_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 16: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_X87_FLOATING_POINT_EXCEPTION_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 17: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_ALIGNMENT_CHECK_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 18: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_MACHINE_CHECK_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 19: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_SIMD_FLOATING_POINT_EXCEPTION_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 20: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_VIRTUALIZATION_EXCEPTION_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 21: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_CONTROL_PROTECTION_EXCEPTION_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 28: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_HYPERVISOR_INJECTION_EXCEPTION_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 29: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_VMM_COMMUNICATION_EXCEPTION_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 30: + sh_iprintf(SH_FAULT,"CPU Fault Hapenned: %s\n",SH_IRQ_SECURITY_EXCEPTION_STRING); + if (frame->vector<32) sh_irq_present_frame(frame); + while (SH_TRUE) {}; + break; + case 32: + if (frame->vector<32) sh_irq_present_frame(frame); + if (irq_managed_by_ioapic) { + sh_iprint(SH_LOG,"Interrupt: PIT timer outside of TSC frequency estimation, managed by IOAPIC.\n"); + sh_lapic_eoi(sh_lapic_get_dev_apic_id((sh_uint64)sh_smp_gs_base()->lapic_id)); + break; + } else { + if (tsc_state==0) { + tsc_start=sh_tsc_read_tsc(); + tsc_state++; + } else if (tsc_state==1) { + tsc_end=sh_tsc_read_tsc(); + tsc_delta=tsc_end-tsc_start; + tsc_state=2; + } else { + sh_iprint(SH_LOG,"Interrupt: PIT timer outside of TSC frequency estimation.\n"); + } + sh_pic_send_eoi(0); + } + break; + case 33: + case 34: + case 35: + case 36: + case 37: + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + if (frame->vector<32) sh_irq_present_frame(frame); + if (irq_managed_by_ioapic) { + if (legacy_irq_handler_array[frame->vector-32]!=SH_NULLPTR) { + legacy_irq_handler_array[frame->vector-32](); + sh_lapic_eoi(sh_lapic_get_dev_apic_id((sh_uint64)sh_smp_gs_base()->lapic_id)); + } else { + sh_lapic_eoi(sh_lapic_get_dev_apic_id((sh_uint64)sh_smp_gs_base()->lapic_id)); + } + break; + } else { + sh_iprintf(SH_LOG,"Interrupt: received interrupt on vector %1u, legacy IRQ not managed by IOAPIC.\n",frame->vector); + while (SH_TRUE) {}; + } + case 254: + if (sh_smp_gs_base()->per_cpu->timer_state==SH_FALSE) sh_iprint(SH_LOG,"Interrupt: LAPIC One Shot Timer finished"); + if (frame->vector<32) sh_irq_present_frame(frame); + if (sh_smp_gs_base()->per_cpu->timer_state==SH_TRUE) sh_smp_gs_base()->per_cpu->timer_state=SH_FALSE; + sh_lapic_eoi(sh_lapic_get_dev_apic_id(sh_smp_gs_base()->lapic_id)); + break; + case 255: + sh_iprint(SH_LOG,"Interrupt: Spurious vector"); + if (frame->vector<32) sh_irq_present_frame(frame); + break; + } +} diff --git a/shelter/lib/src/irq/irq_handler.asm b/shelter/lib/src/irq/irq_handler.asm new file mode 100644 index 0000000..9a096df --- /dev/null +++ b/shelter/lib/src/irq/irq_handler.asm @@ -0,0 +1,86 @@ +; SPDX-License-Identifier: MPL-2.0 +global sh_irq_common_stub +extern sh_irq_dispatch + +%macro SH_IRQ_NOERR 1 +global sh_irq_noerr_%1 +sh_irq_noerr_%1: + push 0 ; fake error code + push %1 ; vector + jmp sh_irq_common_stub +%endmacro + +%macro SH_IRQ_ERR 1 +global sh_irq_err_%1 +sh_irq_err_%1: + push %1 ; vector (CPU already pushed error code) + jmp sh_irq_common_stub +%endmacro + +SH_IRQ_NOERR 0 ; div by zero +SH_IRQ_NOERR 1 ; debug +SH_IRQ_NOERR 2 ; nmi +SH_IRQ_NOERR 3 ; breakpoint +SH_IRQ_NOERR 4 ; overflow +SH_IRQ_NOERR 5 ; bound range exceeded +SH_IRQ_NOERR 6 ; invalid opcode +SH_IRQ_NOERR 7 ; device not available +SH_IRQ_ERR 8 ; double fault +SH_IRQ_NOERR 9 ; coprocessor segment overrun +SH_IRQ_ERR 10 ; invalid tss +SH_IRQ_ERR 11 ; segment not present +SH_IRQ_ERR 12 ; stack segment fault +SH_IRQ_ERR 13 ; general protection fault +SH_IRQ_ERR 14 ; page fault +SH_IRQ_NOERR 16 ; x87 floating point exception +SH_IRQ_ERR 17 ; alignment check +SH_IRQ_NOERR 18 ; machine check +SH_IRQ_NOERR 19 ; simd floating point exception +SH_IRQ_NOERR 20 ; virtualization exception +SH_IRQ_ERR 21 ; control protection exception +SH_IRQ_NOERR 28 ; hypervisor injection exception +SH_IRQ_ERR 29 ; vmm communication exception +SH_IRQ_ERR 30 ; security exception +SH_IRQ_NOERR 32 ; PIC IRQ0 aka PIT tick +SH_IRQ_NOERR 33 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 34 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 35 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 36 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 37 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 38 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 39 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 40 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 41 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 42 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 43 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 44 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 45 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 46 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 47 ; IOAPIC legacy IRQ +SH_IRQ_NOERR 254 ; lapic one shot timer vector +SH_IRQ_NOERR 255 ; spurious vector for lapic + +section .text + +sh_irq_common_stub: + push rax + push rcx + push rdx + push r8 + push r9 + push r10 + push r11 + + mov rdi, rsp + call sh_irq_dispatch + + pop r11 + pop r10 + pop r9 + pop r8 + pop rdx + pop rcx + pop rax + + add rsp, 16 + iretq diff --git a/shelter/lib/src/irq/tss.c b/shelter/lib/src/irq/tss.c new file mode 100644 index 0000000..a92b46c --- /dev/null +++ b/shelter/lib/src/irq/tss.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "irq/tss.h" +#include "cpu/asm.h" +SH_STATUS sh_tss_fill_tss(sh_tss_TSS *tss) { + if (tss==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_mem_set_8((sh_uint8*)tss,0x0,sizeof(sh_tss_TSS)); + void* rsp0=sh_malloc(4096*4); + if (!rsp0) return SH_STATUS_ERROR_NULLPTR_RETURNED; + tss->rsp0=(sh_uint64)rsp0+4096*4; + void* double_fault=sh_malloc(4096*4); + if (!double_fault) return SH_STATUS_ERROR_NULLPTR_RETURNED; + tss->ist1=(sh_uint64)double_fault+4096*4; + void* nmi_fault=sh_malloc(4096*4); + if (!nmi_fault) return SH_STATUS_ERROR_NULLPTR_RETURNED; + tss->ist2=(sh_uint64)nmi_fault+4096*4; + void* page_fault=sh_malloc(4096*4); + if (!page_fault) return SH_STATUS_ERROR_NULLPTR_RETURNED; + tss->ist3=(sh_uint64)page_fault+4096*4; + void* ss_fault=sh_malloc(4096*4); + if (!ss_fault) return SH_STATUS_ERROR_NULLPTR_RETURNED; + tss->ist4=(sh_uint64)ss_fault+4096*4; + tss->iomap_base=sizeof(*tss); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_tss_load_tr(sh_tss_TSS *tss) { + if (tss==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint16 tss_selector=0x28; + sh_asm_ltr(tss_selector); + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/kernel/conf.c b/shelter/lib/src/kernel/conf.c index 8a909a5..79c7daa 100644 --- a/shelter/lib/src/kernel/conf.c +++ b/shelter/lib/src/kernel/conf.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 #include "kernel/conf.h" -#include "kernel/log.h" #include "std/mem.h" +sh_conf_BOOT_CONFIG boot_config; SH_STATUS sh_conf_get_boot_config(sh_conf_BOOT_CONFIG **config) { if (config==SH_NULLPTR) { return SH_STATUS_INVALID_PARAMETER; @@ -15,5 +15,54 @@ SH_STATUS sh_conf_get_boot_config(sh_conf_BOOT_CONFIG **config) { if (sh_mem_compare((*config)->sig_end,sig_end,sizeof(sig_end))==SH_STATUS_MEM_NOT_EQUAL) { return SH_STATUS_INVALID_SIGNATURE; } + sh_mem_copy((sh_uint8*)&boot_config,(sh_uint8*)*config,sizeof(sh_conf_BOOT_CONFIG)); return SH_STATUS_SUCCESS; } +SH_STATUS sh_conf_devs_query(char *sub_path,sh_devs_RESULT *result) { + if (sub_path==SH_NULLPTR || result==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 path_len=sh_string_len(sub_path); + if (path_len==0 || path_len>256) return SH_STATUS_INVALID_PARAMETER; + if (sh_string_compare(sub_path,"/log-level",10)) { + if (path_len==10) { + result->type=SH_DEVS_VALUE; + result->value=boot_config.log_level; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/test-benchmark",15)) { + if (path_len==15) { + result->type=SH_DEVS_BOOL; + result->value=boot_config.test_benchmark; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/bench-iterations",17)) { + if (path_len==17) { + result->type=SH_DEVS_VALUE; + result->value=boot_config.bench_iterations; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/disable-serial-port",20)) { + if (path_len==20) { + result->type=SH_DEVS_BOOL; + result->value=boot_config.disable_serial_port; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/kbd-events-queue-capacity",26)) { + if (path_len==26) { + result->type=SH_DEVS_VALUE; + result->value=boot_config.kbd_events_queue_capacity; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else { + return SH_STATUS_NOT_FOUND; + } +} diff --git a/shelter/lib/src/kernel/efifb.c b/shelter/lib/src/kernel/efifb.c new file mode 100644 index 0000000..bce6e7b --- /dev/null +++ b/shelter/lib/src/kernel/efifb.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "kernel/efifb.h" +sh_uint32 fb_height=0; +sh_uint32 fb_width=0; +sh_uint32 fb_size_bytes=0; +sh_uint32 fb_white=0; +sh_uint32 fb_gray=0; +sh_bool fb_present=SH_FALSE; +sh_uint32 *fb_base=SH_NULLPTR; +sh_uint16 bar_x0=0; +sh_uint16 bar_y0=0; +sh_uint16 bar_x1=0; +sh_uint16 bar_y1=0; +static SH_STATUS sh_efifb_fill_rectangle(sh_uint32 x,sh_uint32 y,sh_uint32 width,sh_uint32 height,sh_uint32 pixel_value) { + if (fb_base==SH_NULLPTR) return SH_STATUS_VA_NOT_MAPPED; + sh_uint32 end_x=x+width; + sh_uint32 end_y=y+height; + if (x>=fb_width || y>=fb_height) return SH_STATUS_BAD_SIZE; + if (end_x>fb_width) end_x=fb_width; + if (end_y>fb_height) end_y=fb_height; + for (sh_uint32 curr_y=y;curr_y=x0+r && x<=x1-r); + if (in_rect) { + fb_base[fb_width*y+x]=color; + continue; + } + sh_uint32 cxL=x0+r; + sh_uint32 cy=y0+r; + sh_uint32 cxR=x1-r; + sh_uint32 dx,dy; + dx=x-cxL; + dy=y-cy; + if (dx*dx+dy*dy<=r*r) { + fb_base[fb_width*y+x]=color; + continue; + } + dx=x-cxR; + dy=y-cy; + if (dx*dx+dy*dy<=r*r) { + fb_base[fb_width*y+x]=color; + continue; + } + } + } +} +SH_STATUS sh_efifb_init_fb(sh_conf_FB_CONFIG *fb_conf,sh_page_PAGE_TABLE_POOL *ptp) { + if (fb_conf==SH_NULLPTR || ptp==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + if (!fb_conf->fb_present) return SH_STATUS_SUCCESS; + fb_height=fb_conf->fb_height; + fb_width=fb_conf->fb_width; + fb_size_bytes=fb_width*fb_height*sizeof(sh_uint32); + if (fb_size_bytes!=fb_conf->size_in_bytes) return SH_STATUS_BAD_SIZE; + SH_STATUS status=sh_page_map_contiguous_pages_range_ptp(ptp,fb_conf->fb_pa,fb_conf->fb_pa,SH_PAGE_PRESENT | SH_PAGE_RW | SH_PAGE_NX | SH_PAGE_PCD,(((fb_size_bytes+4096)/4096)*4096)); + if (sh_status_error(status)) return status; + fb_white=fb_conf->white_pixel_value; + fb_gray=fb_conf->gray_pixel_value; + fb_base=(sh_uint32*)fb_conf->fb_pa; + fb_present=SH_TRUE; + status=sh_efifb_fill_rectangle(fb_conf->text_x,fb_conf->text_y,fb_conf->text_width,fb_conf->text_height,0); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_efifb_init_bar() { + if (!fb_present) return SH_STATUS_SUCCESS; + bar_x0=(sh_uint16)(fb_width*0.3); + bar_x1=(sh_uint16)(fb_width-bar_x0); + bar_y0=(sh_uint16)(fb_height*0.93); + bar_y1=(sh_uint16)(fb_height*0.96); + sh_efifb_draw_rounded_bar(bar_x0,bar_y0,bar_x1,bar_y1,(bar_y1-bar_y0)/2U,fb_gray); + sh_efifb_draw_rounded_bar(bar_x0+3,bar_y0+3,bar_x1-3,bar_y1-3,((bar_y1-3U)-(bar_y0+3U))/2U,0); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_efifb_set_bar(sh_uint8 percent) { + if (!fb_present) return SH_STATUS_SUCCESS; + sh_uint16 bar_width=(sh_uint16)((bar_x1-3U)-(bar_x0+3U)); + sh_uint16 bar_percent=(sh_uint16)(((double)percent/100)*(double)(bar_width)); + sh_uint16 bar_xp=(sh_uint16)(bar_x0+3U+bar_percent); + sh_efifb_fill_rectangle(bar_x0,bar_y0,(bar_x1-bar_x0),(bar_y1-bar_y0),0); + sh_efifb_draw_rounded_bar(bar_x0,bar_y0,bar_x1,bar_y1,(bar_y1-bar_y0)/2U,fb_gray); + sh_efifb_draw_rounded_bar(bar_x0+3,bar_y0+3,bar_x1-3,bar_y1-3,((bar_y1-3U)-(bar_y0+3U))/2U,0); + sh_efifb_draw_rounded_bar(bar_x0+3,bar_y0+3,bar_xp,bar_y1-3,((bar_y1-3U)-(bar_y0+3U))/2U,fb_white); + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/kernel/log.c b/shelter/lib/src/kernel/log.c index 6be1c8a..36061e6 100644 --- a/shelter/lib/src/kernel/log.c +++ b/shelter/lib/src/kernel/log.c @@ -5,6 +5,7 @@ #include "cpu/serial.h" sh_uint8 kernel_log_level=0; sh_bool log_disable_serial_port=SH_FALSE; +sh_bool disable_global_logging_ring=SH_FALSE; sh_ring_RING_BUFFER_HEADER logging_ring={.head=0,.tail=0,.buffer_bytes_size=4*4096,.data_start=(sh_uint8*)SH_VMEM_LAYOUT_LOGGING_RING_BUFFER_VA,.total_bytes_written=0}; void sh_log_load_serial_setting(sh_bool is_disabled) { log_disable_serial_port=is_disabled; @@ -23,10 +24,13 @@ sh_uint32 sh_log_get_logging_ring_size() { sh_uint64 sh_log_get_total_bytes_written() { return logging_ring.total_bytes_written; } +void sh_log_disable_global_logging_ring() { + disable_global_logging_ring=SH_TRUE; +} void sh_log_byte(sh_uint8 byte) { if (log_disable_serial_port) return; sh_serial_send_byte(byte); - sh_ring_write_byte(&logging_ring,(sh_uint8)byte); + if (!disable_global_logging_ring) sh_ring_write_byte(&logging_ring,(sh_uint8)byte); return; } SH_STATUS sh_log_string(const char* str) { @@ -254,6 +258,16 @@ SH_STATUS sh_log_payload(sh_log_OUTPUT_PAYLOAD *payload) { sh_log_string("Heap@"); } else if (payload->output_source==SH_LOG_SOURCE_STD) { sh_log_string("STD @"); + } else if (payload->output_source==SH_LOG_SOURCE_MEMS) { + sh_log_string("MemS@"); + } else if (payload->output_source==SH_LOG_SOURCE_CPUF) { + sh_log_string("CpuF@"); + } else if (payload->output_source==SH_LOG_SOURCE_ACPI) { + sh_log_string("ACPI@"); + } else if (payload->output_source==SH_LOG_SOURCE_TSC) { + sh_log_string("TSC @"); + } else if (payload->output_source==SH_LOG_SOURCE_SMP) { + sh_log_string("SMP @"); } if (payload->output_type==SH_LOG_DEBUG) { sh_log_string("Debug] "); @@ -269,6 +283,8 @@ SH_STATUS sh_log_payload(sh_log_OUTPUT_PAYLOAD *payload) { sh_log_string("Fatal] "); } else if (payload->output_type==SH_LOG_TEST) { sh_log_string("Test] "); + } else if (payload->output_type==SH_LOG_FAULT) { + sh_log_string("Fault] "); } sh_log_uint64(payload->tsc_value); sh_log_string(" : "); @@ -307,6 +323,16 @@ SH_STATUS sh_log_payload_format(sh_log_OUTPUT_PAYLOAD *payload,va_list args) { sh_log_string("Heap@"); } else if (payload->output_source==SH_LOG_SOURCE_STD) { sh_log_string("STD @"); + } else if (payload->output_source==SH_LOG_SOURCE_MEMS) { + sh_log_string("MemS@"); + } else if (payload->output_source==SH_LOG_SOURCE_CPUF) { + sh_log_string("CpuF@"); + } else if (payload->output_source==SH_LOG_SOURCE_ACPI) { + sh_log_string("ACPI@"); + } else if (payload->output_source==SH_LOG_SOURCE_TSC) { + sh_log_string("TSC @"); + } else if (payload->output_source==SH_LOG_SOURCE_SMP) { + sh_log_string("SMP @"); } if (payload->output_type==SH_LOG_DEBUG) { sh_log_string("Debug] "); @@ -322,6 +348,8 @@ SH_STATUS sh_log_payload_format(sh_log_OUTPUT_PAYLOAD *payload,va_list args) { sh_log_string("Fatal] "); } else if (payload->output_type==SH_LOG_TEST) { sh_log_string("Test] "); + } else if (payload->output_type==SH_LOG_FAULT) { + sh_log_string("Fault] "); } sh_log_uint64(payload->tsc_value); sh_log_string(" : "); @@ -454,6 +482,23 @@ SH_STATUS sh_log_fatal(const char* str,sh_log_OUTPUT_SOURCE source) { sh_log_string("\n"); return SH_STATUS_SUCCESS; } +SH_STATUS sh_log_fault(const char* str,sh_log_OUTPUT_SOURCE source) { + if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) { + return SH_STATUS_INVALID_PARAMETER; + } + sh_log_OUTPUT_PAYLOAD payload={ + .output_type=SH_LOG_FAULT, + .output_source=source, + .tsc_value=sh_tsc_get_kernel_current_tsc(), + .message_pointer=str + }; + SH_STATUS status=sh_log_payload(&payload); + if (sh_status_error(status)) { + return status; + } + sh_log_string("\n"); + return SH_STATUS_SUCCESS; +} SH_STATUS sh_log_ltest(const char* str) { if (str==SH_NULLPTR) { return SH_STATUS_INVALID_PARAMETER; @@ -566,6 +611,22 @@ SH_STATUS sh_log_lfatal(const char* str,sh_log_OUTPUT_SOURCE source) { } return SH_STATUS_SUCCESS; } +SH_STATUS sh_log_lfault(const char* str,sh_log_OUTPUT_SOURCE source) { + if (str==SH_NULLPTR || !(sh_log_output_source_valid(source))) { + return SH_STATUS_INVALID_PARAMETER; + } + sh_log_OUTPUT_PAYLOAD payload={ + .output_type=SH_LOG_FAULT, + .output_source=source, + .tsc_value=sh_tsc_get_kernel_current_tsc(), + .message_pointer=str + }; + SH_STATUS status=sh_log_payload(&payload); + if (sh_status_error(status)) { + return status; + } + return SH_STATUS_SUCCESS; +} SH_STATUS sh_log_ftest(const char* format,...) { if (format==SH_NULLPTR) { return SH_STATUS_INVALID_PARAMETER; @@ -699,6 +760,25 @@ SH_STATUS sh_log_ffatal(const sh_log_OUTPUT_SOURCE source,const char* format,... } return SH_STATUS_SUCCESS; } +SH_STATUS sh_log_ffault(const sh_log_OUTPUT_SOURCE source,const char* format,...) { + if (format==SH_NULLPTR || !(sh_log_output_source_valid(source))) { + return SH_STATUS_INVALID_PARAMETER; + } + sh_log_OUTPUT_PAYLOAD payload={ + .output_type=SH_LOG_FAULT, + .output_source=source, + .tsc_value=sh_tsc_get_kernel_current_tsc(), + .message_pointer=format + }; + va_list args; + va_start(args,format); + SH_STATUS status=sh_log_payload_format(&payload,args); + va_end(args); + if (sh_status_error(status)) { + return status; + } + return SH_STATUS_SUCCESS; +} SH_STATUS sh_log_mem_stats(sh_log_OUTPUT_SOURCE source) { sh_page_MEM_STATS mem_stats; sh_page_get_memory_stats(&mem_stats); diff --git a/shelter/lib/src/kernel/tests/test_malloc.c b/shelter/lib/src/kernel/tests/test_malloc.c index 9fdb961..79c0b0b 100644 --- a/shelter/lib/src/kernel/tests/test_malloc.c +++ b/shelter/lib/src/kernel/tests/test_malloc.c @@ -4,7 +4,6 @@ #include "kernel/tests/payloads/test_malloc_payload.h" #include "kernel/log.h" #include "memory/page.h" -#include "memory/heap.h" #include "std/mem.h" #include "std/malloc.h" static sh_uint64 iter_num=10000; @@ -30,7 +29,7 @@ SH_STATUS sh_test_malloc_benchmark() { return SH_STATUS_TEST_FAILED; } } - sh_test_compute_print_stats("sh_malloc for small size",tsc_value,iter_num); + sh_test_compute_print_stats("sh_malloc for small size",tsc_value,iter_num,SH_FALSE); sh_mem_set_8((sh_uint8*)tsc_value,0x00,10000*sizeof(sh_tsc_TSC_VALUE)); for (sh_iter64 i=0;i=n) idx=n-1; return array[idx]; } -SH_STATUS sh_test_compute_print_stats(char* benchname,sh_tsc_TSC_VALUE *tsc_value_array,sh_uint64 array_size) { +SH_STATUS sh_test_compute_print_stats(char* benchname,sh_tsc_TSC_VALUE *tsc_value_array,sh_uint64 array_size,sh_bool use_std_print) { if (tsc_value_array==SH_NULLPTR || array_size==0) return SH_STATUS_INVALID_PARAMETER; sort(tsc_value_array,array_size); sh_uint64 min=tsc_value_array[0]; @@ -30,22 +31,42 @@ SH_STATUS sh_test_compute_print_stats(char* benchname,sh_tsc_TSC_VALUE *tsc_valu sh_uint64 sum=0; for(sh_iter64 i=0;ikernel_ptp,va,pages_count*SH_PAGE_SIZE); if (sh_status_error(status)) sh_heap_internal_crash("Heap free error: unmap failed. Status: %8s\n",status); - // sh_log_flog(SH_LOG_SOURCE_HEAP,"freeed va=0x%x\n",va); status=sh_pez_free_virtual_pages(default_heap->virt_plane,&va,pages_count); if (sh_status_error(status)) sh_heap_internal_crash("Heap free error: virt_plane free failed. Status: %8s\n",status); status=sh_pez_free_physical_pages(default_heap->phys_plane,&pa,pages_count); diff --git a/shelter/lib/src/memory/memory.c b/shelter/lib/src/memory/memory.c new file mode 100644 index 0000000..f52e7d5 --- /dev/null +++ b/shelter/lib/src/memory/memory.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "memory/memory.h" +#include "kernel/log.h" +#include "kernel/test.h" +#include "kernel/efifb.h" +sh_memory_MEMORY_SERVICES *memory_services=SH_NULLPTR; +SH_STATUS sh_memory_init_subsystem(sh_conf_BOOT_CONFIG *boot_config,sh_memory_MEMORY_SERVICES *services) { + if (boot_config==SH_NULLPTR || services==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_log_log("Trying to obtain memory map...",SH_LOG_SOURCE_MEMS); + SH_STATUS status=sh_page_copy_memory_map(); + if (status==SH_STATUS_SUCCESS) { + sh_log_log("Successfully copied memory map.",SH_LOG_SOURCE_PAGE); + sh_log_log("Successfully obtained memory map.",SH_LOG_SOURCE_MEMS); + } else { + sh_log_error("Can't copy memory map.",SH_LOG_SOURCE_PAGE); + sh_log_fatal("Can't obtain memory map.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + sh_log_log("Checking memory map...",SH_LOG_SOURCE_MEMS); + if (status==SH_STATUS_SUCCESS) { + sh_log_log("Successfully checked memory map.",SH_LOG_SOURCE_MEMS); + } else if (status==SH_STATUS_INVALID_SIGNATURE) { + sh_log_fatal("Can't check memory map.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } else if (status==SH_STATUS_MMAP_BUFFER_OVERFLOW) { + sh_log_fatal("Memory map is overflowing. Can't safely continue.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + sh_log_log("Initializing current page table pool...",SH_LOG_SOURCE_MEMS); + status=sh_page_init_ptp(boot_config->page_table_pool_pa,sh_page_get_boot_ptp_va(),boot_config->page_table_allocator_level,&services->kernel_ptp); + if (status==SH_STATUS_PT_POOL_NO_BITMAP_INIT) { + sh_log_fatal("Couldn't initialize current page table pool.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } else if (status==SH_STATUS_PT_POOL_NO_PAGE_SET) { + sh_log_fatal("Couldn't initialize current page table pool.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + sh_log_log("Successfully initialized current page table pool.",SH_LOG_SOURCE_MEMS); + status=sh_efifb_init_fb(&boot_config->fb_config,&services->kernel_ptp); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't initialize EFI FB subsystem. Status: %8s\n",status); + while (SH_TRUE) {}; + } + sh_efifb_init_bar(); + sh_log_log("Successfully initialized EFI FB subsystem.",SH_LOG_SOURCE_MEMS); + sh_log_log("Parsing memory map...",SH_LOG_SOURCE_MEMS); + status=sh_page_analyse_memory_map(&services->kernel_ptp); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't parse memory map. Error code: %8s\n",status); + while (SH_TRUE) {}; + } + sh_log_log("Successfully parsed memory map.",SH_LOG_SOURCE_MEMS); + sh_log_mem_stats(SH_LOG_SOURCE_MEMS); + sh_log_log("Page managment subsystem successfully initialized",SH_LOG_SOURCE_MEMS); + status=sh_slab_reg_phys_alloc_init(&services->slab_reg_phys,&services->kernel_ptp); + if (sh_status_error(status)) { + sh_log_fatal("Couldn't initialize physical region object slab allocator.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + sh_log_log("Successfully initialize physical region object slab allocator.",SH_LOG_SOURCE_MEMS); + sh_log_log("Allocating first slab...",SH_LOG_SOURCE_MEMS); + sh_slab_reg_phys_SLAB_STRUCT *first_slab_rp=SH_NULLPTR; + status=sh_slab_reg_phys_add_slab(&services->slab_reg_phys,&services->kernel_ptp,&first_slab_rp); + if (status!=SH_STATUS_SUCCESS) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't allocate first slab. Error code: %8s\n",status); + while (SH_TRUE) {}; + } else { + sh_log_log("Successfully allocated first slab. Verifying data...",SH_LOG_SOURCE_MEMS); + if (first_slab_rp->free_bitmap[0]!=1 || + first_slab_rp->slab_index!=0 || + first_slab_rp->next!=SH_NULLPTR || + first_slab_rp->prev!=SH_NULLPTR || + first_slab_rp->used_count!=0) { + sh_log_error("One of the attributes inside first slab is wrong.",SH_LOG_SOURCE_MEMS); + sh_log_fatal("Stopping for safety.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } else { + sh_log_log("All attributes are good.",SH_LOG_SOURCE_MEMS); + } + } + status=sh_slab_reg_virt_alloc_init(&services->slab_reg_virt,&services->kernel_ptp); + if (sh_status_error(status)) { + sh_log_fatal("Couldn't initialize virtual region object slab allocator.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + sh_log_log("Successfully initialize virtual region object slab allocator.",SH_LOG_SOURCE_MEMS); + sh_log_log("Allocating first slab...",SH_LOG_SOURCE_MEMS); + sh_slab_reg_virt_SLAB_STRUCT *first_slab_rv=SH_NULLPTR; + status=sh_slab_reg_virt_add_slab(&services->slab_reg_virt,&services->kernel_ptp,&first_slab_rv); + if (status!=SH_STATUS_SUCCESS) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't allocate first slab. Error code: %8s\n",status); + while (SH_TRUE) {}; + } else { + sh_log_log("Successfully allocated first slab. Verifying data...",SH_LOG_SOURCE_MEMS); + if (first_slab_rv->free_bitmap[0]!=1 || + first_slab_rv->slab_index!=0 || + first_slab_rv->next!=SH_NULLPTR || + first_slab_rv->prev!=SH_NULLPTR || + first_slab_rv->used_count!=0) { + sh_log_error("One of the attributes inside first slab is wrong.",SH_LOG_SOURCE_MEMS); + sh_log_fatal("Stopping for safety.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } else { + sh_log_log("All attributes are good.",SH_LOG_SOURCE_MEMS); + } + } + sh_pba_PAGE_BLOCK_ALLOCATOR slab_radix_node_pba; + status=sh_pba_init(&slab_radix_node_pba,SH_VMEM_LAYOUT_SLAB_RADIX_NODE_VA,SH_VMEM_LAYOUT_SLAB_RADIX_NODE_SIZE_BYTES/SH_PAGE_SIZE,SH_SLAB_RADIX_NODE_SLAB_DATA_PAGES); + if (sh_status_error(status)) { + sh_log_fatal("Couldn't initialize PBA for radix nodes slab allocator.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + sh_log_log("Successfully initialize PBA for radix nodes slab allocator.",SH_LOG_SOURCE_MEMS); + status=sh_slab_radix_node_alloc_init(&services->slab_radix_node,&slab_radix_node_pba); + if (sh_status_error(status)) { + sh_log_fatal("Couldn't initialize radix nodes slab allocator.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + sh_log_log("Successfully initialize radix nodes slab allocator.",SH_LOG_SOURCE_MEMS); + sh_log_log("Allocating first slab...",SH_LOG_SOURCE_MEMS); + sh_slab_radix_node_SLAB *first_slab_rn=SH_NULLPTR; + status=sh_slab_radix_node_add_slab(&services->slab_radix_node,&services->kernel_ptp,&first_slab_rn); + if (status!=SH_STATUS_SUCCESS) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't allocate first slab. Error code: %8s\n",status); + while (SH_TRUE) {}; + } else { + sh_log_log("Successfully allocated first slab. Verifying data...",SH_LOG_SOURCE_MEMS); + if (first_slab_rn->free_bitmap[0]!=0x3FFFF || + first_slab_rn->slab_index!=0 || + first_slab_rn->next_slab!=SH_NULLPTR || + first_slab_rn->prev_slab!=SH_NULLPTR || + first_slab_rn->next_partial!=SH_NULLPTR || + first_slab_rn->prev_partial!=SH_NULLPTR || + first_slab_rn->used_count!=0 ) { + sh_log_error("One of the attributes inside first slab is wrong.",SH_LOG_SOURCE_MEMS); + sh_log_fatal("Stopping for safety.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } else { + sh_log_log("All attributes are good.",SH_LOG_SOURCE_MEMS); + } + } + if (boot_config->test_benchmark) { + status=sh_test_slabs_benchmark(&services->slab_reg_phys,&services->slab_reg_virt,&services->slab_radix_node,&services->kernel_ptp); + if (status!=SH_STATUS_SUCCESS) { + sh_log_fatal("Couldn't benchmark one of the slab allocator.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + status=sh_test_radix_benchmark(&services->slab_radix_node,&services->kernel_ptp); + if (status!=SH_STATUS_SUCCESS) { + sh_log_fatal("Couldn't benchmark radix trees subsystem.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + } + sh_log_log("Creating Pez physical plane...",SH_LOG_SOURCE_MEMS); + status=sh_pez_init_physical_plane((sh_uint8*)sh_page_get_physical_bitmap_ptr(),sh_page_get_physical_memory_amount_pages(),&services->slab_reg_phys,&services->slab_radix_node,&services->kernel_ptp,&services->physical_plane); + if (status!=SH_STATUS_SUCCESS) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't create Pez physical plane. Error code: %8s\n",status); + while (SH_TRUE) {}; + } + sh_log_log("Succesfully created Pez physical plane.",SH_LOG_SOURCE_MEMS); + if (boot_config->test_benchmark) { + status=sh_test_pez_benchmark_physical(&services->physical_plane); + if (status!=SH_STATUS_SUCCESS) { + sh_log_fatal("Couldn't benchmark Pez physical plane.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + } + sh_log_log("Creating Pez virtual plane for kernel heap...",SH_LOG_SOURCE_MEMS); + status=sh_pez_init_virtual_plane(SH_VMEM_LAYOUT_HEAP_BIG_VA,&services->slab_reg_virt,&services->slab_radix_node,&services->kernel_ptp,&services->kernel_ptp,&services->virtual_plane_kernel_heap); + if (status!=SH_STATUS_SUCCESS) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't create Pez virtual plane for kernel heap. Error code: %8s\n",status); + while (SH_TRUE) {}; + } + sh_log_log("Succesfully created Pez virtual plane for kernel heap.",SH_LOG_SOURCE_MEMS); + sh_pez_set_available(); + status=sh_heap_init_heap(&services->physical_plane,&services->virtual_plane_kernel_heap,&services->kernel_ptp,&services->kernel_heap); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't initialize kernel heap. Error code: %8s",status); + while (SH_TRUE) {}; + } + sh_uint64 slab_data_pages[8]=SH_SLAB_GENERIC_SLAB_DATA_PAGES; + for (sh_iter64 i=0;i<8;i++) { + status=sh_pba_init(&services->kernel_heap.pba[i],SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_0_VA+i*SH_VMEM_LAYOUT_HEAP_SLAB_SPACING,((SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_0_SIZE_BYTES/SH_PAGE_SIZE)/slab_data_pages[i])*slab_data_pages[i],slab_data_pages[i]); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't create PBA for heap allocations level %8u. Error code: %8s\n",i,status); + while (SH_TRUE); + } + status=sh_slab_generic_alloc_init((sh_uint8)i,&services->kernel_heap.slabs_allocator[i],&services->kernel_heap.pba[i]); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't create slab allocator for heap allocations level %8u. Error code: %8s\n",i,status); + while (SH_TRUE); + } + sh_slab_generic_SLAB *first_slab_generic; + status=sh_slab_generic_add_slab(&services->kernel_heap.slabs_allocator[i],&services->kernel_ptp,&first_slab_generic); + if (status!=SH_STATUS_SUCCESS) { + sh_log_ffatal(SH_LOG_SOURCE_MEMS,"Couldn't allocate first slab for heap allocations level %8u. Error code: %8s\n",i,status); + while (SH_TRUE) {}; + } else { + if (first_slab_generic->free_bitmap[0]!=services->kernel_heap.slabs_allocator[i].bitmap_init || + first_slab_generic->slab_index!=0 || + first_slab_generic->next_slab!=SH_NULLPTR || + first_slab_generic->prev_slab!=SH_NULLPTR || + first_slab_generic->next_partial!=SH_NULLPTR || + first_slab_generic->prev_partial!=SH_NULLPTR || + first_slab_generic->used_count!=0 ) { + sh_log_error("One of the attributes inside first slab is wrong.",SH_LOG_SOURCE_MEMS); + sh_log_fatal("Stopping for safety.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + } + sh_log_flog(SH_LOG_SOURCE_MEMS,"Succesfully created heap slab allocator with level %8u.\n",i); + } + sh_heap_load_default_heap(&services->kernel_heap); + sh_log_log("Succesfully created kernel heap.",SH_LOG_SOURCE_MEMS); + if (boot_config->test_benchmark) { + status=sh_test_malloc_benchmark(); + if (status!=SH_STATUS_SUCCESS) { + sh_log_fatal("Couldn't benchmark Pez physical plane.",SH_LOG_SOURCE_MEMS); + while (SH_TRUE) {}; + } + } + memory_services=services; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_memory_identity_map(sh_page_PHYSICAL_ADDRESS phys_start,sh_uint64 page_count,sh_uint64 flags) { + if (phys_start==0 || page_count==0) return SH_STATUS_INVALID_PARAMETER; + if (memory_services==SH_NULLPTR) return SH_STATUS_MEMORY_SUBSYSTEM_NOT_INITIALIZED; + SH_STATUS status=sh_page_is_va_range_mapped_ptp(&memory_services->kernel_ptp,(sh_page_VIRTUAL_ADDRESS)phys_start,page_count*SH_PAGE_SIZE); + if (status!=SH_STATUS_VA_NOT_MAPPED) { + if (status==SH_STATUS_VA_MAPPED) { + return SH_STATUS_ERROR_VA_FULLY_MAPPED; + } else if (status==SH_STATUS_VA_PARTIALLY_MAPPED) { + return SH_STATUS_ERROR_VA_PARTIALLY_MAPPED; + } + } else if (sh_status_error(status)) { + return status; + } + status=sh_page_map_contiguous_pages_range_ptp(&memory_services->kernel_ptp,(sh_page_VIRTUAL_ADDRESS)phys_start,phys_start,flags,page_count*SH_PAGE_SIZE); + if (sh_status_error(status)) { + return status; + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_memory_devs_query(char *sub_path,sh_devs_RESULT *result) { + if (sub_path==SH_NULLPTR || result==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint64 path_len=sh_string_len(sub_path); + if (path_len==0 || path_len>256) return SH_STATUS_INVALID_PARAMETER; + if (memory_services==SH_NULLPTR) return SH_STATUS_DEVS_NOT_INITIALIZED; + if (sh_string_compare(sub_path,"/free-pages",11)) { + if (path_len==11) { + result->type=SH_DEVS_VALUE; + result->value=memory_services->physical_plane.free_pages; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/used-pages",11)) { + if (path_len==11) { + result->type=SH_DEVS_VALUE; + result->value=memory_services->physical_plane.used_pages; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/total-pages",12)) { + if (path_len==12) { + result->type=SH_DEVS_VALUE; + result->value=sh_page_get_physical_memory_amount_pages(); + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else if (sh_string_compare(sub_path,"/installed-pages",16)) { + if (path_len==16) { + result->type=SH_DEVS_VALUE; + result->value=sh_page_get_installed_memory_bytes()/SH_PAGE_SIZE; + return SH_STATUS_SUCCESS; + } else { + return SH_STATUS_NOT_FOUND; + } + } else { + return SH_STATUS_NOT_FOUND; + } +} diff --git a/shelter/lib/src/memory/page.c b/shelter/lib/src/memory/page.c index 010c419..81d9ac7 100644 --- a/shelter/lib/src/memory/page.c +++ b/shelter/lib/src/memory/page.c @@ -2,6 +2,7 @@ #include "memory/page.h" #include "kernel/log.h" #include "std/mem.h" +#include "std/print.h" __attribute__((section(".bss"))) static sh_uint8 memory_map_buffer[64*1024]; static sh_uint8 *physical_bitmap; @@ -667,3 +668,6 @@ SH_STATUS sh_page_get_memory_stats(sh_page_MEM_STATS *mem_stats) { mem_stats->memory_installed_bytes=physical_memory_installed; return SH_STATUS_SUCCESS; } +sh_uint64 sh_page_get_installed_memory_bytes() { + return physical_memory_installed; +} diff --git a/shelter/lib/src/memory/pez/pez.c b/shelter/lib/src/memory/pez/pez.c index b4f996c..aa95c97 100644 --- a/shelter/lib/src/memory/pez/pez.c +++ b/shelter/lib/src/memory/pez/pez.c @@ -172,7 +172,7 @@ static SH_STATUS sh_pez_internal_scan_size_list_physical(sh_pez_PHYSICAL_PLANE * sh_page_MEM_STATS mem_stats; SH_STATUS status=sh_page_get_memory_stats(&mem_stats); sh_log_fdebug(SH_LOG_SOURCE_PEZ,"Scanning size list radix:\n"); - sh_uint64 free_region_count=0; + __attribute__((__unused__)) sh_uint64 free_region_count=0; sh_log_byte(SH_PEZ_DEBUG_SIZE_LIST_BLOCK_HEADER); sh_log_byte('\n'); for (sh_iter64 i=1;idata_start[ring_buffer->head]=(sh_uint8)string[i]; ring_buffer->head=next_head; + ring_buffer->total_bytes_written++; + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_ring_read_bytes(sh_ring_RING_BUFFER_HEADER *ring_buffer,sh_uint32 bytes_count,void *output) { + if (ring_buffer==SH_NULLPTR || output==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + if (ring_buffer->buffer_bytes_size==0 || ring_buffer->data_start==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint32 size=ring_buffer->buffer_bytes_size; + if (bytes_count>size) return SH_STATUS_TOO_MUCH_DATA; + sh_uint32 head=ring_buffer->head; + sh_uint32 start=(head+size-bytes_count)%size; + for (sh_uint32 i=0;idata_start[idx]; } return SH_STATUS_SUCCESS; } diff --git a/shelter/lib/src/std/malloc.c b/shelter/lib/src/std/malloc.c index f40366e..c27bd45 100644 --- a/shelter/lib/src/std/malloc.c +++ b/shelter/lib/src/std/malloc.c @@ -4,12 +4,15 @@ #include "memory/heap.h" #include "memory/vmem_layout.h" #include "kernel/log.h" +#include "std/smp.h" +sh_SPIN_LOCK malloc_lock=SH_LOCK(); SH_STATUS last_status=0; SH_STATUS sh_malloc_get_last_status() { return last_status; } void* sh_malloc(sh_uint64 size) { if (size==0) return SH_NULLPTR; + sh_spin_lock(&malloc_lock); sh_page_VIRTUAL_ADDRESS va=0; SH_STATUS status; if (size<=1024) { @@ -19,21 +22,22 @@ void* sh_malloc(sh_uint64 size) { status=sh_heap_allocate_pages(pages,&va); } last_status=status; + sh_spin_unlock(&malloc_lock); return (sh_status_error(status))?SH_NULLPTR:(void*)va; } void sh_free(void *ptr) { - if (ptr==SH_NULLPTR) return; + if (ptr == SH_NULLPTR) return; + sh_spin_lock(&malloc_lock); sh_page_VIRTUAL_ADDRESS va=(sh_page_VIRTUAL_ADDRESS)ptr; + SH_STATUS status=SH_STATUS_SUCCESS; if (va>=SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_0_VA && va=SH_VMEM_LAYOUT_HEAP_BIG_VA && va=SH_VMEM_LAYOUT_HEAP_BIG_VA && valog_ring_size/cpu_count; + if (log_ring_size_ap<4) log_ring_size_ap=4; + for (sh_iter64 i=0;iper_cpu->bytes_outputed); + if (!text_to_flush) return SH_STATUS_ERROR_NULLPTR_RETURNED; + sh_spin_lock(&serial_lock); + SH_STATUS status=sh_ring_read_bytes(&ring_buffer_array[sh_smp_gs_base()->per_cpu->cpu_id],sh_smp_gs_base()->per_cpu->bytes_outputed,text_to_flush); + if (sh_status_error(status)) { + sh_spin_unlock(&serial_lock); + return status; + } + sh_log_string(text_to_flush); + sh_spin_unlock(&serial_lock); + sh_free(text_to_flush); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_byte(sh_uint8 byte) { + if (!are_rings_buffer_setup) { + sh_log_byte(byte); + return SH_STATUS_SUCCESS; + } else { + SH_STATUS status=sh_ring_write_byte(&ring_buffer_array[sh_smp_gs_base()->per_cpu->cpu_id],byte); + if (sh_status_error(status)) return status; + sh_smp_gs_base()->per_cpu->bytes_outputed++; + return SH_STATUS_SUCCESS; + } +} +SH_STATUS sh_print_int8(sh_int8 n) { + return sh_print_int64((sh_int64)n); +} +SH_STATUS sh_print_int16(sh_int16 n) { + return sh_print_int64((sh_int64)n); +} +SH_STATUS sh_print_int32(sh_int32 n) { + return sh_print_int64((sh_int64)n); +} +SH_STATUS sh_print_int64(sh_int64 n) { + sh_uint64 absolute_val; + if (n<0) { + sh_print_byte('-'); + absolute_val=(sh_uint64)(-(n+1))+1; + } else { + absolute_val=(sh_uint64)n; + } + return sh_print_uint64(absolute_val); +} +SH_STATUS sh_print_uint8(sh_uint8 n) { + return sh_print_uint64((sh_uint64)n); +} +SH_STATUS sh_print_uint16(sh_uint16 n) { + return sh_print_uint64((sh_uint64)n); +} +SH_STATUS sh_print_uint32(sh_uint32 n) { + return sh_print_uint64((sh_uint64)n); +} +SH_STATUS sh_print_uint64(sh_uint64 n) { + char buf[20]; + sh_uint32 i=0; + if (n==0) { + sh_print_byte('0'); + return SH_STATUS_SUCCESS; + } + while (n>0) { + buf[i++]='0'+(sh_int8)(n%10); + n/=10; + } + while (i--) { + sh_print_byte((sh_uint8)buf[i]); + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_uint8_hex(sh_uint8 n) { + return sh_print_uint64_hex((sh_uint64)n); +} +SH_STATUS sh_print_uint16_hex(sh_uint16 n) { + return sh_print_uint64_hex((sh_uint64)n); +} +SH_STATUS sh_print_uint32_hex(sh_uint32 n) { + return sh_print_uint64_hex((sh_uint64)n); +} +SH_STATUS sh_print_uint64_hex(sh_uint64 n) { + char buf[16]; + sh_uint32 i=0; + const char hex_digits[]="0123456789ABCDEF"; + if (n==0) { + sh_print_byte('0'); + return SH_STATUS_SUCCESS; + } + while (n>0) { + buf[i++]=hex_digits[n & 0xF]; + n>>=4; + } + while (i--) { + sh_print_byte((sh_uint8)buf[i]); + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_uint64_hex_fixed(sh_uint64 n) { + const char hex_digits[]="0123456789ABCDEF"; + for (sh_int8 i=15;i>=0;i--) { + sh_uint8 nibble=(sh_uint8)((n>>(i*4))&0xF); + sh_print_byte((sh_uint8)hex_digits[nibble]); + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_double(double value) { + if (value<0) { + sh_print_byte('-'); + value=-value; + } + sh_uint64 integer_part=(sh_uint64)value; + double fractional_part=value-(double)integer_part; + SH_STATUS status=sh_print_uint64(integer_part); + if (status!=SH_STATUS_SUCCESS) return status; + sh_print_byte('.'); + for (sh_iter64 i=0;i<6;i++) { + fractional_part*=10.0; + sh_uint64 digit=(sh_uint64)fractional_part; + sh_print_byte('0'+(sh_uint8)digit); + fractional_part-=(double)digit; + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print(sh_log_OUTPUT_TYPE output_type,char *text) { + if (text==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_tsc_TSC_VALUE tsc_value=sh_tsc_get_kernel_current_tsc(); + if (!sh_log_output_type_valid(output_type)) return SH_STATUS_INVALID_PARAMETER; + if (output_typeper_cpu->bytes_outputed=0; + sh_asm_cli(); + char *intro="[Shelter:"; + while (*intro) { + sh_print_byte((sh_uint8)*intro++); + } + sh_print_uint64(sh_smp_gs_base()->per_cpu->cpu_id); + sh_print_byte('@'); + char* type=SH_NULLPTR; + if (output_type==SH_DEBUG) { + type="Debug] "; + } else if (output_type==SH_LOG) { + type="Log] "; + } else if (output_type==SH_WARNING) { + type="Warning] "; + } else if (output_type==SH_ERROR) { + type="Error] "; + } else if (output_type==SH_CRITICAL) { + type="Critical] "; + } else if (output_type==SH_FATAL) { + type="Fatal] "; + } else if (output_type==SH_TEST) { + type="Test] "; + } else if (output_type==SH_FAULT) { + type="Fault] "; + } + while (*type) { + sh_print_byte((sh_uint8)*type++); + } + sh_print_uint64(tsc_value); + char *transition=" : "; + while (*transition) { + sh_print_byte((sh_uint8)*transition++); + } + while (*text) { + sh_print_byte((sh_uint8)*text++); + } + SH_STATUS status=sh_print_flush(); + if (sh_status_error(status)) return status; + sh_asm_sti(); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_printf(sh_log_OUTPUT_TYPE output_type,char* format,...) { + if (format==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_tsc_TSC_VALUE tsc_value=sh_tsc_get_kernel_current_tsc(); + if (!sh_log_output_type_valid(output_type)) return SH_STATUS_INVALID_PARAMETER; + if (output_typeper_cpu->bytes_outputed=0; + sh_asm_cli(); + char *intro="[Shelter:"; + while (*intro) { + sh_print_byte((sh_uint8)*intro++); + } + sh_print_uint64(sh_smp_gs_base()->per_cpu->cpu_id); + sh_print_byte('@'); + char* type=SH_NULLPTR; + if (output_type==SH_DEBUG) { + type="Debug] "; + } else if (output_type==SH_LOG) { + type="Log] "; + } else if (output_type==SH_WARNING) { + type="Warning] "; + } else if (output_type==SH_ERROR) { + type="Error] "; + } else if (output_type==SH_CRITICAL) { + type="Critical] "; + } else if (output_type==SH_FATAL) { + type="Fatal] "; + } else if (output_type==SH_TEST) { + type="Test] "; + } else if (output_type==SH_FAULT) { + type="Fault] "; + } + while (*type) { + sh_print_byte((sh_uint8)*type++); + } + sh_print_uint64(tsc_value); + char *transition=" : "; + while (*transition) { + sh_print_byte((sh_uint8)*transition++); + } + va_list args; + va_start(args,format); + for (const char *p=format;*p!='\0';p++) { + if (*p!='%') { + sh_print_byte((sh_uint8)*p); + continue; + } + p++; + switch (*p) { + case 's': { + char *s=va_arg(args,char *); + while (*s) { + sh_print_byte((sh_uint8)*s++); + } + break; + } + case 'd': { + double s=va_arg(args,double); + sh_print_double(s); + break; + } + case '1': { + if (p[1]=='u') { + sh_print_uint8((sh_uint8)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_print_int8((sh_int8)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_print_uint8_hex((sh_uint8)va_arg(args,int)); + p++; + } + break; + } + case '2': { + if (p[1]=='u') { + sh_print_uint16((sh_uint16)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_print_int16((sh_int16)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_print_uint16_hex((sh_uint16)va_arg(args,int)); + p++; + } + break; + } + case '4': { + if (p[1]=='u') { + sh_print_uint32((sh_uint32)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_print_int32((sh_int32)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_print_uint32_hex((sh_uint32)va_arg(args,int)); + p++; + } + break; + } + case '8': { + if (p[1]=='u') { + sh_print_uint64(va_arg(args,unsigned long long)); + p++; + } else if (p[1]=='s') { + sh_print_int64(va_arg(args,long long)); + p++; + } else if (p[1]=='U') { + sh_print_uint64_hex(va_arg(args,unsigned long long)); + p++; + } + break; + } + case 'x': { + sh_uint64 x=va_arg(args,sh_uint64); + sh_print_uint64_hex_fixed(x); + break; + } + case 'c': { + sh_print_byte((sh_uint8)va_arg(args,int)); + break; + } + case '%': { + sh_print_byte('%'); + break; + } + default: + sh_print_byte((sh_uint8)*p); + break; + } + } + va_end(args); + SH_STATUS status=sh_print_flush(); + if (sh_status_error(status)) return status; + sh_asm_sti(); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_ibyte(sh_uint8 byte); +SH_STATUS sh_print_iint8(sh_int8 n); +SH_STATUS sh_print_iint16(sh_int16 n); +SH_STATUS sh_print_iint32(sh_int32 n); +SH_STATUS sh_print_iint64(sh_int64 n); +SH_STATUS sh_print_iuint8(sh_uint8 n); +SH_STATUS sh_print_iuint16(sh_uint16 n); +SH_STATUS sh_print_iuint32(sh_uint32 n); +SH_STATUS sh_print_iuint64(sh_uint64 n); +SH_STATUS sh_print_iuint8_hex(sh_uint8 n); +SH_STATUS sh_print_iuint16_hex(sh_uint16 n); +SH_STATUS sh_print_iuint32_hex(sh_uint32 n); +SH_STATUS sh_print_iuint64_hex(sh_uint64 n); +SH_STATUS sh_print_iuint64_hex_fixed(sh_uint64 n); +SH_STATUS sh_print_idouble(double value); +SH_STATUS sh_print_ibyte(sh_uint8 byte) { + sh_serial_send_byte(byte); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_iint8(sh_int8 n) { + return sh_print_iint64((sh_int64)n); +} +SH_STATUS sh_print_iint16(sh_int16 n) { + return sh_print_iint64((sh_int64)n); +} +SH_STATUS sh_print_iint32(sh_int32 n) { + return sh_print_iint64((sh_int64)n); +} +SH_STATUS sh_print_iint64(sh_int64 n) { + sh_uint64 absolute_val; + if (n<0) { + sh_print_ibyte('-'); + absolute_val=(sh_uint64)(-(n+1))+1; + } else { + absolute_val=(sh_uint64)n; + } + return sh_print_iuint64(absolute_val); +} +SH_STATUS sh_print_iuint8(sh_uint8 n) { + return sh_print_iuint64((sh_uint64)n); +} +SH_STATUS sh_print_iuint16(sh_uint16 n) { + return sh_print_iuint64((sh_uint64)n); +} +SH_STATUS sh_print_iuint32(sh_uint32 n) { + return sh_print_iuint64((sh_uint64)n); +} +SH_STATUS sh_print_iuint64(sh_uint64 n) { + char buf[20]; + sh_uint32 i=0; + if (n==0) { + sh_print_ibyte('0'); + return SH_STATUS_SUCCESS; + } + while (n>0) { + buf[i++]='0'+(sh_int8)(n%10); + n/=10; + } + while (i--) { + sh_print_ibyte((sh_uint8)buf[i]); + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_iuint8_hex(sh_uint8 n) { + return sh_print_iuint64_hex((sh_uint64)n); +} +SH_STATUS sh_print_iuint16_hex(sh_uint16 n) { + return sh_print_iuint64_hex((sh_uint64)n); +} +SH_STATUS sh_print_iuint32_hex(sh_uint32 n) { + return sh_print_iuint64_hex((sh_uint64)n); +} +SH_STATUS sh_print_iuint64_hex(sh_uint64 n) { + char buf[16]; + sh_uint32 i=0; + const char hex_digits[]="0123456789ABCDEF"; + if (n==0) { + sh_print_ibyte('0'); + return SH_STATUS_SUCCESS; + } + while (n>0) { + buf[i++]=hex_digits[n & 0xF]; + n>>=4; + } + while (i--) { + sh_print_ibyte((sh_uint8)buf[i]); + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_iuint64_hex_fixed(sh_uint64 n) { + const char hex_digits[]="0123456789ABCDEF"; + for (sh_int8 i=15;i>=0;i--) { + sh_uint8 nibble=(sh_uint8)((n>>(i*4))&0xF); + sh_print_ibyte((sh_uint8)hex_digits[nibble]); + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_print_idouble(double value) { + if (value<0) { + sh_print_ibyte('-'); + value=-value; + } + sh_uint64 integer_part=(sh_uint64)value; + double fractional_part=value-(double)integer_part; + SH_STATUS status=sh_print_iuint64(integer_part); + if (status!=SH_STATUS_SUCCESS) return status; + sh_print_ibyte('.'); + for (sh_iter64 i=0;i<6;i++) { + fractional_part*=10.0; + sh_uint64 digit=(sh_uint64)fractional_part; + sh_print_ibyte('0'+(sh_uint8)digit); + fractional_part-=(double)digit; + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_iprint(sh_log_OUTPUT_TYPE output_type,char *text) { + if (text==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_tsc_TSC_VALUE tsc_value=sh_tsc_get_kernel_current_tsc(); + if (!sh_log_output_type_valid(output_type)) return SH_STATUS_INVALID_PARAMETER; + if (output_typelapic_id) was_locked_by_me=SH_TRUE; + if (!was_locked_by_me) { + sh_spin_lock(&serial_lock); + } + char *intro="[Shelter:"; + while (*intro) { + sh_print_ibyte((sh_uint8)*intro++); + } + sh_print_iuint64(sh_smp_gs_base()->per_cpu->cpu_id); + sh_print_ibyte('@'); + char* type=SH_NULLPTR; + if (output_type==SH_DEBUG) { + type="Debug] "; + } else if (output_type==SH_LOG) { + type="Log] "; + } else if (output_type==SH_WARNING) { + type="Warning] "; + } else if (output_type==SH_ERROR) { + type="Error] "; + } else if (output_type==SH_CRITICAL) { + type="Critical] "; + } else if (output_type==SH_FATAL) { + type="Fatal] "; + } else if (output_type==SH_TEST) { + type="Test] "; + } else if (output_type==SH_FAULT) { + type="Fault] "; + } + while (*type) { + sh_print_ibyte((sh_uint8)*type++); + } + sh_print_iuint64(tsc_value); + char *transition=" : "; + while (*transition) { + sh_print_ibyte((sh_uint8)*transition++); + } + while (*text) { + sh_print_ibyte((sh_uint8)*text++); + } + if (!was_locked_by_me) sh_spin_unlock(&serial_lock); + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_iprintf(sh_log_OUTPUT_TYPE output_type,char* format,...) { + if (format==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_tsc_TSC_VALUE tsc_value=sh_tsc_get_kernel_current_tsc(); + if (!sh_log_output_type_valid(output_type)) return SH_STATUS_INVALID_PARAMETER; + if (output_typelapic_id) was_locked_by_me=SH_TRUE; + if (!was_locked_by_me) { + sh_spin_lock(&serial_lock); + } + char *intro="[Shelter:"; + while (*intro) { + sh_print_ibyte((sh_uint8)*intro++); + } + sh_print_iuint64(sh_smp_gs_base()->per_cpu->cpu_id); + sh_print_ibyte('@'); + char* type=SH_NULLPTR; + if (output_type==SH_DEBUG) { + type="Debug] "; + } else if (output_type==SH_LOG) { + type="Log] "; + } else if (output_type==SH_WARNING) { + type="Warning] "; + } else if (output_type==SH_ERROR) { + type="Error] "; + } else if (output_type==SH_CRITICAL) { + type="Critical] "; + } else if (output_type==SH_FATAL) { + type="Fatal] "; + } else if (output_type==SH_TEST) { + type="Test] "; + } else if (output_type==SH_FAULT) { + type="Fault] "; + } + while (*type) { + sh_print_ibyte((sh_uint8)*type++); + } + sh_print_iuint64(tsc_value); + char *transition=" : "; + while (*transition) { + sh_print_ibyte((sh_uint8)*transition++); + } + va_list args; + va_start(args,format); + for (const char *p=format;*p!='\0';p++) { + if (*p!='%') { + sh_print_ibyte((sh_uint8)*p); + continue; + } + p++; + switch (*p) { + case 's': { + char *s=va_arg(args,char *); + while (*s) { + sh_print_ibyte((sh_uint8)*s++); + } + break; + } + case 'd': { + double s=va_arg(args,double); + sh_print_idouble(s); + break; + } + case '1': { + if (p[1]=='u') { + sh_print_iuint8((sh_uint8)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_print_iint8((sh_int8)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_print_iuint8_hex((sh_uint8)va_arg(args,int)); + p++; + } + break; + } + case '2': { + if (p[1]=='u') { + sh_print_iuint16((sh_uint16)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_print_iint16((sh_int16)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_print_iuint16_hex((sh_uint16)va_arg(args,int)); + p++; + } + break; + } + case '4': { + if (p[1]=='u') { + sh_print_iuint32((sh_uint32)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_print_iint32((sh_int32)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_print_iuint32_hex((sh_uint32)va_arg(args,int)); + p++; + } + break; + } + case '8': { + if (p[1]=='u') { + sh_print_iuint64(va_arg(args,unsigned long long)); + p++; + } else if (p[1]=='s') { + sh_print_iint64(va_arg(args,long long)); + p++; + } else if (p[1]=='U') { + sh_print_iuint64_hex(va_arg(args,unsigned long long)); + p++; + } + break; + } + case 'x': { + sh_uint64 x=va_arg(args,sh_uint64); + sh_print_iuint64_hex_fixed(x); + break; + } + case 'c': { + sh_print_ibyte((sh_uint8)va_arg(args,int)); + break; + } + case '%': { + sh_print_ibyte('%'); + break; + } + default: + sh_print_ibyte((sh_uint8)*p); + break; + } + } + va_end(args); + if (!was_locked_by_me) sh_spin_unlock(&serial_lock); + return SH_STATUS_SUCCESS; +} +typedef struct sh_sprint_WRITER { + sh_uint8 *out; + sh_uint8 *end; +} sh_sprint_WRITER; +static inline SH_STATUS sh_sprint_byte(sh_sprint_WRITER *w,sh_uint8 c) { + if(w->out>=w->end) return SH_STATUS_TOO_MUCH_DATA; + *w->out++=c; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_sprint_int8(sh_sprint_WRITER *w,sh_int8 n); +SH_STATUS sh_sprint_int16(sh_sprint_WRITER *w,sh_int16 n); +SH_STATUS sh_sprint_int32(sh_sprint_WRITER *w,sh_int32 n); +SH_STATUS sh_sprint_int64(sh_sprint_WRITER *w,sh_int64 n); +SH_STATUS sh_sprint_uint8(sh_sprint_WRITER *w,sh_uint8 n); +SH_STATUS sh_sprint_uint16(sh_sprint_WRITER *w,sh_uint16 n); +SH_STATUS sh_sprint_uint32(sh_sprint_WRITER *w,sh_uint32 n); +SH_STATUS sh_sprint_uint64(sh_sprint_WRITER *w,sh_uint64 n); +SH_STATUS sh_sprint_uint8_hex(sh_sprint_WRITER *w,sh_uint8 n); +SH_STATUS sh_sprint_uint16_hex(sh_sprint_WRITER *w,sh_uint16 n); +SH_STATUS sh_sprint_uint32_hex(sh_sprint_WRITER *w,sh_uint32 n); +SH_STATUS sh_sprint_uint64_hex(sh_sprint_WRITER *w,sh_uint64 n); +SH_STATUS sh_sprint_uint64_hex_fixed(sh_sprint_WRITER *w,sh_uint64 n); +SH_STATUS sh_sprint_double(sh_sprint_WRITER *w,double value); +SH_STATUS sh_sprint_int8(sh_sprint_WRITER *w,sh_int8 n) { + return sh_sprint_int64(w,(sh_int64)n); +} +SH_STATUS sh_sprint_int16(sh_sprint_WRITER *w,sh_int16 n) { + return sh_sprint_int64(w,(sh_int64)n); +} +SH_STATUS sh_sprint_int32(sh_sprint_WRITER *w,sh_int32 n) { + return sh_sprint_int64(w,(sh_int64)n); +} +SH_STATUS sh_sprint_int64(sh_sprint_WRITER *w,sh_int64 n) { + sh_uint64 absolute_val; + if (n<0) { + SH_STATUS status=sh_sprint_byte(w,'-'); + if (sh_status_error(status)) return status; + absolute_val=(sh_uint64)(-(n+1))+1; + } else { + absolute_val=(sh_uint64)n; + } + return sh_sprint_uint64(w,absolute_val); +} +SH_STATUS sh_sprint_uint8(sh_sprint_WRITER *w,sh_uint8 n) { + return sh_sprint_uint64(w,(sh_int64)n); +} +SH_STATUS sh_sprint_uint16(sh_sprint_WRITER *w,sh_uint16 n) { + return sh_sprint_uint64(w,(sh_int64)n); +} +SH_STATUS sh_sprint_uint32(sh_sprint_WRITER *w,sh_uint32 n) { + return sh_sprint_uint64(w,(sh_int64)n); +} +SH_STATUS sh_sprint_uint64(sh_sprint_WRITER *w,sh_uint64 n) { + char buf[20]; + sh_uint32 i=0; + if (n==0) return sh_sprint_byte(w,'0'); + while (n>0) { + buf[i++]='0'+(sh_int8)(n%10); + n/=10; + } + while (i--) { + SH_STATUS status=sh_sprint_byte(w,(sh_uint8)buf[i]); + if (sh_status_error(status)) return status; + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_sprint_uint8_hex(sh_sprint_WRITER *w,sh_uint8 n) { + return sh_sprint_uint64_hex(w,(sh_uint64)n); +} +SH_STATUS sh_sprint_uint16_hex(sh_sprint_WRITER *w,sh_uint16 n) { + return sh_sprint_uint64_hex(w,(sh_uint64)n); +} +SH_STATUS sh_sprint_uint32_hex(sh_sprint_WRITER *w,sh_uint32 n) { + return sh_sprint_uint64_hex(w,(sh_uint64)n); +} +SH_STATUS sh_sprint_uint64_hex(sh_sprint_WRITER *w,sh_uint64 n) { + char buf[16]; + sh_uint32 i=0; + const char hex_digits[]="0123456789ABCDEF"; + if (n==0) return sh_sprint_byte(w,'0'); + while (n>0) { + buf[i++]=hex_digits[n & 0xF]; + n>>=4; + } + while (i--) { + SH_STATUS status=sh_sprint_byte(w,(sh_uint8)buf[i]); + if (sh_status_error(status)) return status; + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_sprint_uint64_hex_fixed(sh_sprint_WRITER *w,sh_uint64 n) { + const char hex[]="0123456789ABCDEF"; + for (sh_int8 i=15;i>=0;i--) { + char c=hex[(n>>(i*4))&0xF]; + SH_STATUS status=sh_sprint_byte(w,(sh_uint8)c); + if (sh_status_error(status)) return status; + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_sprint_double(sh_sprint_WRITER *w,double value) { + SH_STATUS status; + if(value<0) { + status=sh_sprint_byte(w,'-'); + if (sh_status_error(status)) return status; + value= -value; + } + sh_uint64 int_part=(sh_uint64)value; + double frac=value-(double)int_part; + status=sh_sprint_uint64(w,int_part); + if (sh_status_error(status)) return status; + status=sh_sprint_byte(w,'.'); + if (sh_status_error(status)) return status; + for(sh_iter64 i=0;i<6;i++) { + frac*=10.0; + sh_uint64 d=(sh_uint64)frac; + status=sh_sprint_byte(w,(sh_uint8)'0'+(sh_uint8)d); + if (sh_status_error(status)) return status; + frac-=(double)d; + } + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_sprintf(char *output_string,sh_uint64 output_len,char *format,...) { + if (format==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_asm_cli(); + sh_sprint_WRITER w={ + .out=(sh_uint8*)output_string, + .end=(sh_uint8*)output_string+output_len + }; + va_list args; + va_start(args,format); + for (const char *p=format;*p!='\0';p++) { + if (*p!='%') { + sh_sprint_byte(&w,(sh_uint8)*p); + continue; + } + p++; + switch (*p) { + case 's': { + char *s=va_arg(args,char *); + while (*s) { + sh_sprint_byte(&w,(sh_uint8)*s++); + } + break; + } + case 'd': { + double s=va_arg(args,double); + sh_sprint_double(&w,s); + break; + } + case '1': { + if (p[1]=='u') { + sh_sprint_uint8(&w,(sh_uint8)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_sprint_int8(&w,(sh_int8)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_sprint_uint8_hex(&w,(sh_uint8)va_arg(args,int)); + p++; + } + break; + } + case '2': { + if (p[1]=='u') { + sh_sprint_uint16(&w,(sh_uint16)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_sprint_int16(&w,(sh_int16)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_sprint_uint16_hex(&w,(sh_uint16)va_arg(args,int)); + p++; + } + break; + } + case '4': { + if (p[1]=='u') { + sh_sprint_uint32(&w,(sh_uint32)va_arg(args,int)); + p++; + } else if (p[1]=='s') { + sh_sprint_int32(&w,(sh_int32)va_arg(args,int)); + p++; + } else if (p[1]=='U') { + sh_sprint_uint32_hex(&w,(sh_uint32)va_arg(args,int)); + p++; + } + break; + } + case '8': { + if (p[1]=='u') { + sh_sprint_uint64(&w,va_arg(args,unsigned long long)); + p++; + } else if (p[1]=='s') { + sh_sprint_int64(&w,va_arg(args,long long)); + p++; + } else if (p[1]=='U') { + sh_sprint_uint64_hex(&w,va_arg(args,unsigned long long)); + p++; + } + break; + } + case 'x': { + sh_uint64 x=va_arg(args,sh_uint64); + sh_sprint_uint64_hex_fixed(&w,x); + break; + } + case 'c': { + sh_sprint_byte(&w,(sh_uint8)va_arg(args,int)); + break; + } + case '%': { + sh_sprint_byte(&w,'%'); + break; + } + default: + sh_sprint_byte(&w,(sh_uint8)*p); + break; + } + } + va_end(args); + SH_STATUS status=sh_sprint_byte(&w,'\0'); + if (sh_status_error(status)) { + output_string[output_len-1]='\0'; + } + sh_asm_sti(); + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/std/queue.c b/shelter/lib/src/std/queue.c new file mode 100644 index 0000000..5249c19 --- /dev/null +++ b/shelter/lib/src/std/queue.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "std/queue.h" +#include "std/malloc.h" +#include "std/smp.h" +SH_STATUS sh_queue_event_init(sh_queue_KBD_EVENT *q,sh_uint32 capacity) { + if (q==SH_NULLPTR || capacity==0) return SH_STATUS_INVALID_PARAMETER; + q->buffer=(sh_kbd_EVENT*)sh_malloc(sizeof(sh_kbd_EVENT)*capacity); + if (!q->buffer) return SH_STATUS_ERROR_NULLPTR_RETURNED; + q->capacity=capacity; + q->write_index=0; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_queue_event_push(sh_queue_KBD_EVENT *q,sh_kbd_EVENT ev) { + if (q==SH_NULLPTR || q->buffer==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_uint32 idx=q->write_index % q->capacity; + q->buffer[idx]=ev; + sh_mb(); + q->write_index++; + return SH_STATUS_SUCCESS; +} +SH_STATUS sh_queue_event_destroy(sh_queue_KBD_EVENT *q) { + if (q==SH_NULLPTR || q->buffer==SH_NULLPTR) return SH_STATUS_INVALID_PARAMETER; + sh_free(q->buffer); + if (sh_status_error(sh_malloc_get_last_status())) return sh_malloc_get_last_status(); + q->capacity=0; + q->write_index=0; + return SH_STATUS_SUCCESS; +} diff --git a/shelter/lib/src/std/smp.c b/shelter/lib/src/std/smp.c new file mode 100644 index 0000000..5da61a3 --- /dev/null +++ b/shelter/lib/src/std/smp.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "std/smp.h" +static sh_int16 max_cpu=-1; +void sh_smp_set_cpu_count(sh_int16 cpu_count) { + max_cpu=cpu_count; + return; +} +sh_int16 sh_smp_get_cpu_count() { + return max_cpu; +} diff --git a/shelter/lib/src/std/string.c b/shelter/lib/src/std/string.c new file mode 100644 index 0000000..b54ee0c --- /dev/null +++ b/shelter/lib/src/std/string.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: MPL-2.0 +#include "std/string.h" +sh_uint64 sh_string_len(char *str) { + sh_uint64 i=0; + if (!str) return 0; + while (str[i]) i++; + return i; +} +sh_bool sh_string_compare(char *str1,char *str2,sh_uint64 length) { + sh_uint64 i=0; + if (!str1 || !str2) return SH_FALSE; + while (i'9') break; + sh_uint64 digit=(sh_uint64)(*str-'0'); + if (result>(SH_UINT64_MAX-digit)/10) return SH_UINT64_MAX; + result=result*10+digit; + str++; + } + return result; +} diff --git a/shelter/main.c b/shelter/main.c index d7c037c..3231fd4 100644 --- a/shelter/main.c +++ b/shelter/main.c @@ -3,18 +3,38 @@ #include "kernel/test.h" #include "kernel/log.h" #include "kernel/conf.h" +#include "kernel/efifb.h" #include "cpu/tsc.h" #include "cpu/serial.h" -#include "memory/page.h" -#include "memory/slab.h" -#include "memory/pba.h" -#include "memory/heap.h" -#include "memory/pez/radix.h" -#include "memory/pez/pez.h" +#include "cpu/ap.h" +#include "memory/memory.h" +#include "irq/tss.h" +#include "irq/gdt.h" +#include "irq/idt.h" +#include "irq/gsi.h" +#include "devs/acpi.h" +#include "devs/acpi_tables/madt.h" +#include "devs/apic/lapic.h" +#include "devs/apic/ioapic.h" +#include "devs/input/kbd.h" +#include "devs/input/ps2.h" +char temp[256]; int main() { sh_tsc_init_tsc(); + sh_ap_CPU_STRUCT this_cpu_struct; + this_cpu_struct.c_entry_point_stack_top_va=0; + this_cpu_struct.lapic_id=SH_UINT32_MAX; + this_cpu_struct.tss_selector=0; + sh_ap_PER_CPU per_cpu; + per_cpu.cpu_id=0; + per_cpu.bytes_outputed=0; + per_cpu.timer_state=SH_FALSE; + per_cpu.temp_buffer=temp; + per_cpu.temp_buffer_size=256; + this_cpu_struct.per_cpu=(&per_cpu); + sh_smp_write_gs_base((sh_uint64)&this_cpu_struct); sh_log_string("\n---------------------------\n\n"); - sh_log_log("Shelter v0.1",SH_LOG_SOURCE_MAIN); + sh_log_log("Shelter v0.2",SH_LOG_SOURCE_MAIN); sh_conf_BOOT_CONFIG *boot_config=SH_NULLPTR; SH_STATUS status=sh_conf_get_boot_config(&boot_config); if (status==SH_STATUS_INVALID_SIGNATURE) { @@ -42,219 +62,203 @@ int main() { sh_log_uint64((sh_uint64)sh_log_get_log_level()); sh_log_string("\n"); sh_log_flog(SH_LOG_SOURCE_MAIN,"Set logging ring buffer to %2u pages.\n",boot_config->log_ring_size); - sh_log_log("Trying to obtain memory map...",SH_LOG_SOURCE_MAIN); - status=sh_page_copy_memory_map(); + sh_memory_MEMORY_SERVICES memory_services; + status=sh_memory_init_subsystem(boot_config,&memory_services); + if (sh_status_error(status)) { + sh_log_fatal("Couldn't initialize memory subsystem.",SH_LOG_SOURCE_MAIN); + while (SH_TRUE) {}; + } + sh_log_log("Successfully initialized memory subsystem.",SH_LOG_SOURCE_MAIN); + sh_efifb_set_bar(1); + sh_tss_TSS tss; + status=sh_tss_fill_tss(&tss); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't setup TSS structure. Status: %8s",status); + while (1) {}; + } + sh_log_log("Successfully initialized TSS structure.",SH_LOG_SOURCE_MAIN); + sh_gdt_GDT gdt; + status=sh_gdt_fill_gdt(&tss,&gdt); + if (sh_status_error(status)) { + sh_log_fatal("Couldn't setup GDT structure.",SH_LOG_SOURCE_MAIN); + while (1) {}; + } + sh_gdt_load_gdtr(&gdt); + sh_gdt_reload_registers(); + sh_smp_write_gs_base((sh_uint64)&this_cpu_struct); + sh_log_log("Successfully loaded GDT.",SH_LOG_SOURCE_MAIN); + sh_tss_load_tr(&tss); + sh_log_log("Successfully loaded TSS.",SH_LOG_SOURCE_MAIN); + sh_idt_IDT idt; + status=sh_idt_fill_idt(&idt); + if (sh_status_error(status)) { + sh_log_fatal("Couldn't setup IDT structure.",SH_LOG_SOURCE_MAIN); + while (1) {}; + } + sh_log_log("Successfully initialized IDT structure.",SH_LOG_SOURCE_MAIN); + sh_idt_load_idtr(&idt); + sh_log_log("Successfully loaded IDT.",SH_LOG_SOURCE_MAIN); + sh_efifb_set_bar(2); + sh_log_log("IDT enabled. Parsing ACPI RSDP...",SH_LOG_SOURCE_MAIN); + sh_apci_ACPI_POINTERS_ROOT acpi_pointers_root; + status=sh_acpi_parse_rsdp(boot_config->acpi_rsdp,boot_config->acpi_ver,&acpi_pointers_root); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't parse ACPI RSDP. Error code: %8s",status); + while (1) {}; + } + sh_log_log("Parsed ACPI RSDP.",SH_LOG_SOURCE_MAIN); + if (acpi_pointers_root.xsdt==0) { + sh_log_log("ACPI v1 is being used. It's not supported for the moment.",SH_LOG_SOURCE_MAIN); + while (1) {}; + } else { + sh_log_log("ACPI v2 is being used.",SH_LOG_SOURCE_MAIN); + } + sh_log_log("Parsing ACPI XSDT...",SH_LOG_SOURCE_MAIN); + sh_acpi_ACPI_XSDT_BODY xsdt_body; + status=sh_acpi_parse_xsdt(acpi_pointers_root.xsdt,&xsdt_body); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't parse ACPI XSDT. Error code: %8s",status); + while (1) {}; + } + sh_log_log("Parsed ACPI XSDT.",SH_LOG_SOURCE_MAIN); + sh_log_log("Parsing ACPI tables...",SH_LOG_SOURCE_MAIN); + sh_acpi_ACPI_TABLES acpi_tables; + status=sh_acpi_parse_tables(&xsdt_body,&acpi_tables); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't parse ACPI tables. Error code: %8s",status); + while (1) {}; + } + sh_log_log("Parsed ACPI tables.",SH_LOG_SOURCE_MAIN); + sh_log_log("Parsing MADT table...",SH_LOG_SOURCE_MAIN); + if (acpi_tables.madt_physical_address==0) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Didn't found MADT table. Can't continue."); + while (1) {}; + } + status=sh_acpi_madt_parse(acpi_tables.madt_physical_address); + if (sh_status_error(status)) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't parse ACPI MADT table. Error code: %8s",status); + while (1) {}; + } + sh_log_log("Parsed MADT table.",SH_LOG_SOURCE_MAIN); + sh_efifb_set_bar(3); + status=sh_ioapic_mask_all(); + if (sh_status_error(status)) { + sh_log_fatal("Couldn't disable all IOAPIC GSI lines.",SH_LOG_SOURCE_MAIN); + while (SH_TRUE) {}; + } + sh_log_log("Checking somes flags...",SH_LOG_SOURCE_MAIN); + sh_bool has_hypervisor=sh_tsc_has_hypervisor(); + if (has_hypervisor) { + sh_log_log("Shelter is running on a hypervisor (according to CPUID).",SH_LOG_SOURCE_MAIN); + sh_log_warning("This may result in jitter during the CPU frequency estimation.",SH_LOG_SOURCE_MAIN); + } else { + sh_log_log("Shelter isn't running on a hypervisor (according to CPUID).",SH_LOG_SOURCE_MAIN); + } + sh_bool constant_tsc=sh_tsc_is_tsc_constant(); + if (constant_tsc) { + sh_log_log("TSC is constant (according to CPUID).",SH_LOG_SOURCE_MAIN); + } else { + sh_log_log("TSC isn't constant (according to CPUID).",SH_LOG_SOURCE_MAIN); + } + sh_uint64 cpu_freq; + status=sh_tsc_get_cpu_freq_cpuid(&cpu_freq); + if (status==SH_STATUS_UNAVAILABLE) { + sh_log_log("CPU frequence from CPUID is unavailable.",SH_LOG_SOURCE_MAIN); + } else { + sh_log_flog(SH_LOG_SOURCE_MAIN,"CPU frequence from CPUID: %8u hz",cpu_freq); + } if (status==SH_STATUS_SUCCESS) { - sh_log_log("Successfully copied memory map.",SH_LOG_SOURCE_PAGE); - sh_log_log("Successfully obtained memory map.",SH_LOG_SOURCE_MAIN); + sh_log_log("Using provided CPU frequence by CPUID",SH_LOG_SOURCE_MAIN); } else { - sh_log_error("Can't copy memory map.",SH_LOG_SOURCE_PAGE); - sh_log_fatal("Can't obtain memory map.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; + sh_log_log("Estimating CPU frequence...",SH_LOG_SOURCE_MAIN); + cpu_freq=sh_tsc_estimate_cpu_freq(); + sh_log_flog(SH_LOG_SOURCE_MAIN,"Estimated CPU frequence: %8u hz\n",cpu_freq); } - sh_log_log("Checking memory map...",SH_LOG_SOURCE_MAIN); - if (status==SH_STATUS_SUCCESS) { - sh_log_log("Successfully checked memory map.",SH_LOG_SOURCE_MAIN); - } else if (status==SH_STATUS_INVALID_SIGNATURE) { - sh_log_fatal("Can't check memory map.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } else if (status==SH_STATUS_MMAP_BUFFER_OVERFLOW) { - sh_log_fatal("Memory map is overflowing. Can't safely continue.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; + sh_tsc_load_cpu_freq(cpu_freq); + sh_log_log("Calibrating LAPIC...",SH_LOG_SOURCE_MAIN); + sh_lapic_DEVICE *lapic=sh_lapic_get_dev_apic_id(0); + if (!lapic) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't get LAPIC."); + while (1) {}; } - sh_log_log("Initializing current page table pool...",SH_LOG_SOURCE_MAIN); - sh_page_PAGE_TABLE_POOL kernel_ptp; - status=sh_page_init_ptp(boot_config->page_table_pool_pa,sh_page_get_boot_ptp_va(),boot_config->page_table_allocator_level,&kernel_ptp); - if (status==SH_STATUS_PT_POOL_NO_BITMAP_INIT) { - sh_log_fatal("Couldn't initialize current page table pool.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } else if (status==SH_STATUS_PT_POOL_NO_PAGE_SET) { - sh_log_fatal("Couldn't initialize current page table pool.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } - sh_log_log("Successfully initialized current page table pool.",SH_LOG_SOURCE_MAIN); - sh_log_log("Parsing memory map...",SH_LOG_SOURCE_MAIN); - status=sh_page_analyse_memory_map(&kernel_ptp); + sh_log_flog(SH_LOG_SOURCE_MAIN,"Obtained LAPIC.\n"); + status=sh_lapic_init_dev(0xFF,lapic); if (sh_status_error(status)) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't parse memory map. Error code: %8s\n",status); - while (SH_TRUE) {}; + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't initialize LAPIC."); + while (1) {}; } - sh_log_log("Successfully parsed memory map.",SH_LOG_SOURCE_MAIN); - sh_log_mem_stats(SH_LOG_SOURCE_MAIN); - sh_log_log("Page managment subsystem successfully initialized",SH_LOG_SOURCE_MAIN); - sh_slab_reg_phys_SLAB_ALLOCATOR slab_reg_phys; - status=sh_slab_reg_phys_alloc_init(&slab_reg_phys,&kernel_ptp); + sh_log_flog(SH_LOG_SOURCE_MAIN,"Initialized LAPIC.\n"); + status=sh_lapic_calibrate(lapic,cpu_freq); if (sh_status_error(status)) { - sh_log_fatal("Couldn't initialize physical region object slab allocator.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't calibrate LAPIC."); + while (1) {}; } - sh_log_log("Successfully initialize physical region object slab allocator.",SH_LOG_SOURCE_MAIN); - sh_log_log("Allocating first slab...",SH_LOG_SOURCE_MAIN); - sh_slab_reg_phys_SLAB_STRUCT *first_slab_rp=SH_NULLPTR; - status=sh_slab_reg_phys_add_slab(&slab_reg_phys,&kernel_ptp,&first_slab_rp); - if (status!=SH_STATUS_SUCCESS) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't allocate first slab. Error code: %8s\n",status); - while (SH_TRUE) {}; - } else { - sh_log_log("Successfully allocated first slab. Verifying data...",SH_LOG_SOURCE_MAIN); - if (first_slab_rp->free_bitmap[0]!=1 || - first_slab_rp->slab_index!=0 || - first_slab_rp->next!=SH_NULLPTR || - first_slab_rp->prev!=SH_NULLPTR || - first_slab_rp->used_count!=0) { - sh_log_error("One of the attributes inside first slab is wrong.",SH_LOG_SOURCE_MAIN); - sh_log_fatal("Stopping for safety.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } else { - sh_log_log("All attributes are good.",SH_LOG_SOURCE_MAIN); - } + sh_log_flog(SH_LOG_SOURCE_MAIN,"Calibration ended with LAPIC frequency being %8u hz.\n",sh_lapic_get_frequency()); + sh_int16 current_cpu=sh_lapic_get_current_core(); + if (current_cpu<0) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't obtain current CPU LAPIC id."); + while (1) {}; } - sh_slab_reg_virt_SLAB_ALLOCATOR slab_reg_virt; - status=sh_slab_reg_virt_alloc_init(&slab_reg_virt,&kernel_ptp); + sh_log_flog(SH_LOG_SOURCE_MAIN,"Current CPU have a LAPIC id of %1u.\n",(sh_uint8)current_cpu); + lapic=sh_lapic_get_dev_apic_id((sh_uint64)current_cpu); + if (!lapic) { + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't get LAPIC."); + while (1) {}; + } + sh_log_flog(SH_LOG_SOURCE_MAIN,"Obtained LAPIC of this CPU.\n"); + sh_log_log("Preparing application processors initialization...",SH_LOG_SOURCE_MAIN); + status=sh_ap_load_gdt_32(); if (sh_status_error(status)) { - sh_log_fatal("Couldn't initialize virtual region object slab allocator.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't generate 32-bits GDT for AP trampoline. Status code: %8s\n",status); + while (1) {}; } - sh_log_log("Successfully initialize virtual region object slab allocator.",SH_LOG_SOURCE_MAIN); - sh_log_log("Allocating first slab...",SH_LOG_SOURCE_MAIN); - sh_slab_reg_virt_SLAB_STRUCT *first_slab_rv=SH_NULLPTR; - status=sh_slab_reg_virt_add_slab(&slab_reg_virt,&kernel_ptp,&first_slab_rv); - if (status!=SH_STATUS_SUCCESS) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't allocate first slab. Error code: %8s\n",status); - while (SH_TRUE) {}; - } else { - sh_log_log("Successfully allocated first slab. Verifying data...",SH_LOG_SOURCE_MAIN); - if (first_slab_rv->free_bitmap[0]!=1 || - first_slab_rv->slab_index!=0 || - first_slab_rv->next!=SH_NULLPTR || - first_slab_rv->prev!=SH_NULLPTR || - first_slab_rv->used_count!=0) { - sh_log_error("One of the attributes inside first slab is wrong.",SH_LOG_SOURCE_MAIN); - sh_log_fatal("Stopping for safety.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } else { - sh_log_log("All attributes are good.",SH_LOG_SOURCE_MAIN); - } - } - sh_pba_PAGE_BLOCK_ALLOCATOR slab_radix_node_pba; - status=sh_pba_init(&slab_radix_node_pba,SH_VMEM_LAYOUT_SLAB_RADIX_NODE_VA,SH_VMEM_LAYOUT_SLAB_RADIX_NODE_SIZE_BYTES/SH_PAGE_SIZE,SH_SLAB_RADIX_NODE_SLAB_DATA_PAGES); + sh_log_log("Generated 32-bits GDT for AP trampoline.",SH_LOG_SOURCE_MAIN); + status=sh_ap_prepare_for_smp_launch(sh_lapic_get_by_apic_id_array(),sh_lapic_get_max_apic_id(),sh_lapic_get_lapic_count(),boot_config,&idt); if (sh_status_error(status)) { - sh_log_fatal("Couldn't initialize PBA for radix nodes slab allocator.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; + sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't prepare for AP launch. Status code: %8s\n",status); + while (1) {}; } - sh_log_log("Successfully initialize PBA for radix nodes slab allocator.",SH_LOG_SOURCE_MAIN); - struct sh_slab_radix_node_SLAB_ALLOCATOR slab_radix_node; - status=sh_slab_radix_node_alloc_init(&slab_radix_node,&slab_radix_node_pba); + sh_log_log("Succesfully prepared for AP launch.",SH_LOG_SOURCE_MAIN); + status=sh_ap_start_ap_boot_procedure(boot_config); if (sh_status_error(status)) { - sh_log_fatal("Couldn't initialize radix nodes slab allocator.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; + sh_printf(SH_FATAL,"Couldn't start AP boot procedure. Status code: %8s\n",status); + while (1) {}; } - sh_log_log("Successfully initialize radix nodes slab allocator.",SH_LOG_SOURCE_MAIN); - sh_log_log("Allocating first slab...",SH_LOG_SOURCE_MAIN); - sh_slab_radix_node_SLAB *first_slab_rn=SH_NULLPTR; - status=sh_slab_radix_node_add_slab(&slab_radix_node,&kernel_ptp,&first_slab_rn); - if (status!=SH_STATUS_SUCCESS) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't allocate first slab. Error code: %8s\n",status); - while (SH_TRUE) {}; - } else { - sh_log_log("Successfully allocated first slab. Verifying data...",SH_LOG_SOURCE_MAIN); - if (first_slab_rn->free_bitmap[0]!=0x3FFFF || - first_slab_rn->slab_index!=0 || - first_slab_rn->next_slab!=SH_NULLPTR || - first_slab_rn->prev_slab!=SH_NULLPTR || - first_slab_rn->next_partial!=SH_NULLPTR || - first_slab_rn->prev_partial!=SH_NULLPTR || - first_slab_rn->used_count!=0 ) { - sh_log_error("One of the attributes inside first slab is wrong.",SH_LOG_SOURCE_MAIN); - sh_log_fatal("Stopping for safety.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } else { - sh_log_log("All attributes are good.",SH_LOG_SOURCE_MAIN); - } + sh_print(SH_LOG,"Succesfully started all APs.\n"); + status=sh_gsi_irq_switch(); + if (sh_status_error(status)) { + sh_printf(SH_FATAL,"Couldn't switch legacy IRQ management to IOAPIC. Status code: %8s\n",status); + while (1) {}; } + sh_printf(SH_LOG,"Succesfully switched legacy IRQ management to IOAPIC.\n"); + sh_efifb_set_bar(4); if (boot_config->test_benchmark) { - status=sh_test_slabs_benchmark(&slab_reg_phys,&slab_reg_virt,&slab_radix_node,&kernel_ptp); + status=sh_test_benchmark_queues(); if (status!=SH_STATUS_SUCCESS) { - sh_log_fatal("Couldn't benchmark one of the slab allocator.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } - status=sh_test_radix_benchmark(&slab_radix_node,&kernel_ptp); - if (status!=SH_STATUS_SUCCESS) { - sh_log_fatal("Couldn't benchmark radix trees subsystem.",SH_LOG_SOURCE_MAIN); + sh_print(SH_FATAL,"Couldn't benchmark keyboard events queues.\n"); while (SH_TRUE) {}; } } - sh_log_log("Creating Pez physical plane...",SH_LOG_SOURCE_MAIN); - sh_pez_PHYSICAL_PLANE physical_plane; - status=sh_pez_init_physical_plane((sh_uint8*)sh_page_get_physical_bitmap_ptr(),sh_page_get_physical_memory_amount_pages(),&slab_reg_phys,&slab_radix_node,&kernel_ptp,&physical_plane); - if (status!=SH_STATUS_SUCCESS) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't create Pez physical plane. Error code: %8s\n",status); - while (SH_TRUE) {}; - } - sh_log_log("Succesfully created Pez physical plane.",SH_LOG_SOURCE_MAIN); - if (boot_config->test_benchmark) { - status=sh_test_pez_benchmark_physical(&physical_plane); - if (status!=SH_STATUS_SUCCESS) { - sh_log_fatal("Couldn't benchmark Pez physical plane.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } - } - sh_log_log("Creating Pez virtual plane for kernel heap...",SH_LOG_SOURCE_MAIN); - sh_pez_VIRTUAL_PLANE virtual_plane_kernel_heap; - status=sh_pez_init_virtual_plane(SH_VMEM_LAYOUT_HEAP_BIG_VA,&slab_reg_virt,&slab_radix_node,&kernel_ptp,&kernel_ptp,&virtual_plane_kernel_heap); - if (status!=SH_STATUS_SUCCESS) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't create Pez virtual plane for kernel heap. Error code: %8s\n",status); - while (SH_TRUE) {}; - } - sh_log_log("Succesfully created Pez virtual plane for kernel heap.",SH_LOG_SOURCE_MAIN); - sh_pez_set_available(); - sh_heap_KERNEL_HEAP kernel_heap; - status=sh_heap_init_heap(&physical_plane,&virtual_plane_kernel_heap,&kernel_ptp,&kernel_heap); + status=sh_kbd_init_devs(); if (sh_status_error(status)) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't initialize kernel heap. Error code: %8s",status); - while (SH_TRUE) {}; + sh_printf(SH_FATAL,"Couldn't initialized keyboard subsystem. Status code: %8s\n",status); + while (1) {}; } - sh_uint64 slab_data_pages[8]=SH_SLAB_GENERIC_SLAB_DATA_PAGES; - for (sh_iter64 i=0;i<8;i++) { - status=sh_pba_init(&kernel_heap.pba[i],SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_0_VA+i*SH_VMEM_LAYOUT_HEAP_SLAB_SPACING,((SH_VMEM_LAYOUT_HEAP_SLAB_LEVEL_0_SIZE_BYTES/SH_PAGE_SIZE)/slab_data_pages[i])*slab_data_pages[i],slab_data_pages[i]); - if (sh_status_error(status)) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't create PBA for heap allocations level %8u. Error code: %8s\n",i,status); - while (SH_TRUE); - } - status=sh_slab_generic_alloc_init((sh_uint8)i,&kernel_heap.slabs_allocator[i],&kernel_heap.pba[i]); - if (sh_status_error(status)) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't create slab allocator for heap allocations level %8u. Error code: %8s\n",i,status); - while (SH_TRUE); - } - sh_slab_generic_SLAB *first_slab_generic; - status=sh_slab_generic_add_slab(&kernel_heap.slabs_allocator[i],&kernel_ptp,&first_slab_generic); - if (status!=SH_STATUS_SUCCESS) { - sh_log_ffatal(SH_LOG_SOURCE_MAIN,"Couldn't allocate first slab for heap allocations level %8u. Error code: %8s\n",i,status); - while (SH_TRUE) {}; - } else { - if (first_slab_generic->free_bitmap[0]!=kernel_heap.slabs_allocator[i].bitmap_init || - first_slab_generic->slab_index!=0 || - first_slab_generic->next_slab!=SH_NULLPTR || - first_slab_generic->prev_slab!=SH_NULLPTR || - first_slab_generic->next_partial!=SH_NULLPTR || - first_slab_generic->prev_partial!=SH_NULLPTR || - first_slab_generic->used_count!=0 ) { - sh_log_error("One of the attributes inside first slab is wrong.",SH_LOG_SOURCE_MAIN); - sh_log_fatal("Stopping for safety.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } - } - sh_log_flog(SH_LOG_SOURCE_MAIN,"Succesfully created heap slab allocator with level %8u.\n",i); + sh_printf(SH_LOG,"Succesfully initialized keyboard subsystem.\n"); + status=sh_ps2_driver_init(); + if (sh_status_error(status)) { + sh_printf(SH_FATAL,"Couldn't initialized PS2 driver. Status code: %8s\n",status); + while (1) {}; } - sh_heap_load_default_heap(&kernel_heap); - sh_log_log("Succesfully created kernel heap.",SH_LOG_SOURCE_MAIN); - if (boot_config->test_benchmark) { - status=sh_test_malloc_benchmark(); - if (status!=SH_STATUS_SUCCESS) { - sh_log_fatal("Couldn't benchmark Pez physical plane.",SH_LOG_SOURCE_MAIN); - while (SH_TRUE) {}; - } + sh_printf(SH_LOG,"Succesfully initialized PS2 driver.\n"); + status=sh_ps2_disable_scanning(); + if (sh_status_error(status)) { + sh_printf(SH_FATAL,"Couldn't disable PS2 scanning. Status code: %8s\n",status); + while (1) {}; } + sh_printf(SH_LOG,"Succesfully disabled PS2 scanning.\n"); + sh_efifb_set_bar(5); + sh_efifb_set_bar(100); while (1) {}; return 0; } diff --git a/shelter/shelter.json b/shelter/shelter.json new file mode 100644 index 0000000..a9da1a2 --- /dev/null +++ b/shelter/shelter.json @@ -0,0 +1,26 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Shelter build", + "actions":[ + { + "action":"run_submodule", + "args":{ + "file_variables":false, + "file":"tools/python_script.json", + "wait":true, + "block_if_fail":true + } + }, + { + "action":"run_submodule", + "args":{ + "file_variables":false, + "file":"kernel.json", + "wait":true, + "block_if_fail":true + } + } + ] +} diff --git a/shelter/tools/python_script.json b/shelter/tools/python_script.json new file mode 100644 index 0000000..41862ea --- /dev/null +++ b/shelter/tools/python_script.json @@ -0,0 +1,79 @@ +{ + "version":"0.1", + "root_folder":"%filefolder%", + "run_context":"sub", + "name":"Shelter python scripts execution", + "actions":[ + { + "action":"run_actions_parallel", + "args":{ + "actions":[ + { + "action":"run_command_wait", + "args":{ + "command_variables":true, + "command":[ + "$PYTHON_EXE$", + "checker/vmem_layout_check.py", + "%rootcallerfolder%/shelter/lib/include/memory/vmem_layout.h" + ], + "show_output":"on_failure", + "success_status":[ + 0 + ], + "ignore_success_status":false + } + }, + { + "action":"save_command_content", + "args":{ + "command_variables":true, + "command":[ + "$PYTHON_EXE$", + "generator/pez_alloc_free_payload_gen.py" + ], + "success_status":[ + 0 + ], + "ignore_success_status":true, + "command_output_file_variables":true, + "command_output_file":"%rootcallerfolder%/shelter/lib/include/kernel/tests/payloads/test_pez_payload.h" + } + }, + { + "action":"save_command_content", + "args":{ + "command_variables":true, + "command":[ + "$PYTHON_EXE$", + "generator/radix_tree_payload_gen.py" + ], + "success_status":[ + 0 + ], + "ignore_success_status":true, + "command_output_file_variables":true, + "command_output_file":"%rootcallerfolder%/shelter/lib/include/kernel/tests/payloads/test_radix_payload.h" + } + }, + { + "action":"save_command_content", + "args":{ + "command_variables":true, + "command":[ + "$PYTHON_EXE$", + "generator/malloc_payload_gen.py" + ], + "success_status":[ + 0 + ], + "ignore_success_status":true, + "command_output_file_variables":true, + "command_output_file":"%rootcallerfolder%/shelter/lib/include/kernel/tests/payloads/test_malloc_payload.h" + } + } + ] + } + } + ] +} diff --git a/vyld/_vyx_start.c b/vybuild/_vyx_start.c similarity index 100% rename from vyld/_vyx_start.c rename to vybuild/_vyx_start.c diff --git a/vybuild/api.h b/vybuild/api.h new file mode 100644 index 0000000..9d5da67 --- /dev/null +++ b/vybuild/api.h @@ -0,0 +1,80 @@ +#ifndef SPX_API_H +#define SPX_API_H + +#include +#include + +#include "params.h" + +#define CRYPTO_ALGNAME "SPHINCS+" + +#define CRYPTO_SECRETKEYBYTES SPX_SK_BYTES +#define CRYPTO_PUBLICKEYBYTES SPX_PK_BYTES +#define CRYPTO_BYTES SPX_BYTES +#define CRYPTO_SEEDBYTES 3*SPX_N + +// We only need this header for the macros that define keys and signature length, we don't need these fonction +#ifdef VYBUILD_DEFINE_CRYPTOS_FUNCTION_FROM_HEADER +/* + * Returns the length of a secret key, in bytes + */ +unsigned long long crypto_sign_secretkeybytes(void); + +/* + * Returns the length of a public key, in bytes + */ +unsigned long long crypto_sign_publickeybytes(void); + +/* + * Returns the length of a signature, in bytes + */ +unsigned long long crypto_sign_bytes(void); + +/* + * Returns the length of the seed required to generate a key pair, in bytes + */ +unsigned long long crypto_sign_seedbytes(void); + +/* + * Generates a SPHINCS+ key pair given a seed. + * Format sk: [SK_SEED || SK_PRF || PUB_SEED || root] + * Format pk: [root || PUB_SEED] + */ +int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed); + +/* + * Generates a SPHINCS+ key pair. + * Format sk: [SK_SEED || SK_PRF || PUB_SEED || root] + * Format pk: [root || PUB_SEED] + */ +int crypto_sign_keypair(unsigned char *pk, unsigned char *sk); + +/** + * Returns an array containing a detached signature. + */ +int crypto_sign_signature(uint8_t *sig, size_t *siglen, + const uint8_t *m, size_t mlen, const uint8_t *sk); + +/** + * Verifies a detached signature and message under a given public key. + */ +int crypto_sign_verify(const uint8_t *sig, size_t siglen, + const uint8_t *m, size_t mlen, const uint8_t *pk); + +/** + * Returns an array containing the signature followed by the message. + */ +int crypto_sign(unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk); + +/** + * Verifies a given signature-message pair under a given public key. + */ +int crypto_sign_open(unsigned char *m, unsigned long long *mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk); + +#endif +#endif diff --git a/vybuild/build.sh b/vybuild/build.sh new file mode 100755 index 0000000..3001d26 --- /dev/null +++ b/vybuild/build.sh @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: MPL-2.0 +g++ -I. vybuild/vybuild.cpp vybuild/vybuild-actions.cpp vybuild/vybuild-parser.cpp vybuild/vybuild-vars.cpp vybuild/vybuild-cache.cpp vybuild/vybuild-vyld.cpp vybuild/vybuild-condition.cpp vybuild/vybuild-fat32.cpp vybuild/vybuild-disk.cpp vybuild/xxhash.c -std=c++20 -lz -luuid -o vybuild/vybuild diff --git a/vyld/elfio.hpp b/vybuild/elfio.hpp similarity index 100% rename from vyld/elfio.hpp rename to vybuild/elfio.hpp diff --git a/vyld/elfio/elf_types.hpp b/vybuild/elfio/elf_types.hpp similarity index 100% rename from vyld/elfio/elf_types.hpp rename to vybuild/elfio/elf_types.hpp diff --git a/vyld/elfio/elfio_array.hpp b/vybuild/elfio/elfio_array.hpp similarity index 100% rename from vyld/elfio/elfio_array.hpp rename to vybuild/elfio/elfio_array.hpp diff --git a/vyld/elfio/elfio_dump.hpp b/vybuild/elfio/elfio_dump.hpp similarity index 100% rename from vyld/elfio/elfio_dump.hpp rename to vybuild/elfio/elfio_dump.hpp diff --git a/vyld/elfio/elfio_dynamic.hpp b/vybuild/elfio/elfio_dynamic.hpp similarity index 100% rename from vyld/elfio/elfio_dynamic.hpp rename to vybuild/elfio/elfio_dynamic.hpp diff --git a/vyld/elfio/elfio_header.hpp b/vybuild/elfio/elfio_header.hpp similarity index 100% rename from vyld/elfio/elfio_header.hpp rename to vybuild/elfio/elfio_header.hpp diff --git a/vyld/elfio/elfio_modinfo.hpp b/vybuild/elfio/elfio_modinfo.hpp similarity index 100% rename from vyld/elfio/elfio_modinfo.hpp rename to vybuild/elfio/elfio_modinfo.hpp diff --git a/vyld/elfio/elfio_note.hpp b/vybuild/elfio/elfio_note.hpp similarity index 100% rename from vyld/elfio/elfio_note.hpp rename to vybuild/elfio/elfio_note.hpp diff --git a/vyld/elfio/elfio_relocation.hpp b/vybuild/elfio/elfio_relocation.hpp similarity index 100% rename from vyld/elfio/elfio_relocation.hpp rename to vybuild/elfio/elfio_relocation.hpp diff --git a/vyld/elfio/elfio_section.hpp b/vybuild/elfio/elfio_section.hpp similarity index 100% rename from vyld/elfio/elfio_section.hpp rename to vybuild/elfio/elfio_section.hpp diff --git a/vyld/elfio/elfio_segment.hpp b/vybuild/elfio/elfio_segment.hpp similarity index 100% rename from vyld/elfio/elfio_segment.hpp rename to vybuild/elfio/elfio_segment.hpp diff --git a/vyld/elfio/elfio_strings.hpp b/vybuild/elfio/elfio_strings.hpp similarity index 100% rename from vyld/elfio/elfio_strings.hpp rename to vybuild/elfio/elfio_strings.hpp diff --git a/vyld/elfio/elfio_symbols.hpp b/vybuild/elfio/elfio_symbols.hpp similarity index 100% rename from vyld/elfio/elfio_symbols.hpp rename to vybuild/elfio/elfio_symbols.hpp diff --git a/vyld/elfio/elfio_utils.hpp b/vybuild/elfio/elfio_utils.hpp similarity index 100% rename from vyld/elfio/elfio_utils.hpp rename to vybuild/elfio/elfio_utils.hpp diff --git a/vyld/elfio/elfio_version.hpp b/vybuild/elfio/elfio_version.hpp similarity index 100% rename from vyld/elfio/elfio_version.hpp rename to vybuild/elfio/elfio_version.hpp diff --git a/vyld/elfio/elfio_versym.hpp b/vybuild/elfio/elfio_versym.hpp similarity index 100% rename from vyld/elfio/elfio_versym.hpp rename to vybuild/elfio/elfio_versym.hpp diff --git a/vybuild/json.hpp b/vybuild/json.hpp new file mode 100644 index 0000000..e2bb851 --- /dev/null +++ b/vybuild/json.hpp @@ -0,0 +1,25830 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + +/****************************************************************************\ + * Note on documentation: The source files contain links to the online * + * documentation of the public API at https://json.nlohmann.me. This URL * + * contains the most recent documentation and should also be applicable to * + * previous versions; documentation for deprecated functions is not * + * removed, but marked deprecated. See "Generate documentation" section in * + * file docs/README.md. * +\****************************************************************************/ + +#ifndef INCLUDE_NLOHMANN_JSON_HPP_ +#define INCLUDE_NLOHMANN_JSON_HPP_ + +#include // all_of, find, for_each +#include // nullptr_t, ptrdiff_t, size_t +#include // hash, less +#include // initializer_list +#ifndef JSON_NO_IO + #include // istream, ostream +#endif // JSON_NO_IO +#include // random_access_iterator_tag +#include // unique_ptr +#include // string, stoi, to_string +#include // declval, forward, move, pair, swap +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// This file contains all macro definitions affecting or depending on the ABI + +#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK + #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) + #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 + #warning "Already included a different version of the library!" + #endif + #endif +#endif + +#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum) + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 0 +#endif + +#ifndef JSON_DIAGNOSTIC_POSITIONS + #define JSON_DIAGNOSTIC_POSITIONS 0 +#endif + +#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +#endif + +#if JSON_DIAGNOSTICS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS +#endif + +#if JSON_DIAGNOSTIC_POSITIONS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS +#endif + +#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp +#else + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION + #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +#endif + +// Construct the namespace ABI tags component +#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \ + NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) + +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS) + +// Construct the namespace version component +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ + _v ## major ## _ ## minor ## _ ## patch +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) + +#if NLOHMANN_JSON_NAMESPACE_NO_VERSION +#define NLOHMANN_JSON_NAMESPACE_VERSION +#else +#define NLOHMANN_JSON_NAMESPACE_VERSION \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ + NLOHMANN_JSON_VERSION_MINOR, \ + NLOHMANN_JSON_VERSION_PATCH) +#endif + +// Combine namespace components +#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b +#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ + NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) + +#ifndef NLOHMANN_JSON_NAMESPACE +#define NLOHMANN_JSON_NAMESPACE \ + nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN +#define NLOHMANN_JSON_NAMESPACE_BEGIN \ + namespace nlohmann \ + { \ + inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) \ + { +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_END +#define NLOHMANN_JSON_NAMESPACE_END \ + } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ + } // namespace nlohmann +#endif + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // transform +#include // array +#include // forward_list +#include // inserter, front_inserter, end +#include // map +#include // string +#include // tuple, make_tuple +#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible +#include // unordered_map +#include // pair, declval +#include // valarray + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // nullptr_t +#include // exception +#if JSON_DIAGNOSTICS + #include // accumulate +#endif +#include // runtime_error +#include // to_string +#include // vector + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // uint8_t +#include // string + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // declval, pair +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// https://en.cppreference.com/w/cpp/experimental/is_detected +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + + +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson +// SPDX-License-Identifier: MIT + +/* Hedley - https://nemequ.github.io/hedley + * Created by Evan Nemerson + * SPDX-License-Identifier: CC0-1.0 + */ + +#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) +#if defined(JSON_HEDLEY_VERSION) + #undef JSON_HEDLEY_VERSION +#endif +#define JSON_HEDLEY_VERSION 15 + +#if defined(JSON_HEDLEY_STRINGIFY_EX) + #undef JSON_HEDLEY_STRINGIFY_EX +#endif +#define JSON_HEDLEY_STRINGIFY_EX(x) #x + +#if defined(JSON_HEDLEY_STRINGIFY) + #undef JSON_HEDLEY_STRINGIFY +#endif +#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) + +#if defined(JSON_HEDLEY_CONCAT_EX) + #undef JSON_HEDLEY_CONCAT_EX +#endif +#define JSON_HEDLEY_CONCAT_EX(a,b) a##b + +#if defined(JSON_HEDLEY_CONCAT) + #undef JSON_HEDLEY_CONCAT +#endif +#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) + +#if defined(JSON_HEDLEY_CONCAT3_EX) + #undef JSON_HEDLEY_CONCAT3_EX +#endif +#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c + +#if defined(JSON_HEDLEY_CONCAT3) + #undef JSON_HEDLEY_CONCAT3 +#endif +#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) + +#if defined(JSON_HEDLEY_VERSION_ENCODE) + #undef JSON_HEDLEY_VERSION_ENCODE +#endif +#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) + #undef JSON_HEDLEY_VERSION_DECODE_MAJOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) + #undef JSON_HEDLEY_VERSION_DECODE_MINOR +#endif +#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) + +#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) + #undef JSON_HEDLEY_VERSION_DECODE_REVISION +#endif +#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) + +#if defined(JSON_HEDLEY_GNUC_VERSION) + #undef JSON_HEDLEY_GNUC_VERSION +#endif +#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#elif defined(__GNUC__) + #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) +#endif + +#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) + #undef JSON_HEDLEY_GNUC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GNUC_VERSION) + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION) + #undef JSON_HEDLEY_MSVC_VERSION +#endif +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) +#elif defined(_MSC_FULL_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) +#elif defined(_MSC_VER) && !defined(__ICL) + #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) + #undef JSON_HEDLEY_MSVC_VERSION_CHECK +#endif +#if !defined(JSON_HEDLEY_MSVC_VERSION) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) +#elif defined(_MSC_VER) && (_MSC_VER >= 1200) + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) +#else + #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION) + #undef JSON_HEDLEY_INTEL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) +#elif defined(__INTEL_COMPILER) && !defined(__ICL) + #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_VERSION) + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #undef JSON_HEDLEY_INTEL_CL_VERSION +#endif +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) + #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) +#endif + +#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) + #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_INTEL_CL_VERSION) + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION) + #undef JSON_HEDLEY_PGI_VERSION +#endif +#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) + #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) +#endif + +#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) + #undef JSON_HEDLEY_PGI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PGI_VERSION) + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #undef JSON_HEDLEY_SUNPRO_VERSION +#endif +#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) +#elif defined(__SUNPRO_C) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) +#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) +#elif defined(__SUNPRO_CC) + #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) +#endif + +#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) + #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_SUNPRO_VERSION) + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION +#endif +#if defined(__EMSCRIPTEN__) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) +#endif + +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) + #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION) + #undef JSON_HEDLEY_ARM_VERSION +#endif +#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) +#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) + #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) +#endif + +#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) + #undef JSON_HEDLEY_ARM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_ARM_VERSION) + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION) + #undef JSON_HEDLEY_IBM_VERSION +#endif +#if defined(__ibmxl__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) +#elif defined(__xlC__) && defined(__xlC_ver__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) +#elif defined(__xlC__) + #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) +#endif + +#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) + #undef JSON_HEDLEY_IBM_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IBM_VERSION) + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_VERSION) + #undef JSON_HEDLEY_TI_VERSION +#endif +#if \ + defined(__TI_COMPILER_VERSION__) && \ + ( \ + defined(__TMS470__) || defined(__TI_ARM__) || \ + defined(__MSP430__) || \ + defined(__TMS320C2000__) \ + ) +#if (__TI_COMPILER_VERSION__ >= 16000000) + #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif +#endif + +#if defined(JSON_HEDLEY_TI_VERSION_CHECK) + #undef JSON_HEDLEY_TI_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_VERSION) + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #undef JSON_HEDLEY_TI_CL2000_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) + #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL2000_VERSION) + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #undef JSON_HEDLEY_TI_CL430_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) + #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL430_VERSION) + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #undef JSON_HEDLEY_TI_ARMCL_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) + #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) + #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #undef JSON_HEDLEY_TI_CL6X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) + #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL6X_VERSION) + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #undef JSON_HEDLEY_TI_CL7X_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) + #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CL7X_VERSION) + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #undef JSON_HEDLEY_TI_CLPRU_VERSION +#endif +#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) + #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) + #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION) + #undef JSON_HEDLEY_CRAY_VERSION +#endif +#if defined(_CRAYC) + #if defined(_RELEASE_PATCHLEVEL) + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) + #else + #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) + #undef JSON_HEDLEY_CRAY_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_CRAY_VERSION) + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION) + #undef JSON_HEDLEY_IAR_VERSION +#endif +#if defined(__IAR_SYSTEMS_ICC__) + #if __VER__ > 1000 + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) + #else + #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) + #endif +#endif + +#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) + #undef JSON_HEDLEY_IAR_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_IAR_VERSION) + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION) + #undef JSON_HEDLEY_TINYC_VERSION +#endif +#if defined(__TINYC__) + #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) +#endif + +#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) + #undef JSON_HEDLEY_TINYC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION) + #undef JSON_HEDLEY_DMC_VERSION +#endif +#if defined(__DMC__) + #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) +#endif + +#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) + #undef JSON_HEDLEY_DMC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_DMC_VERSION) + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #undef JSON_HEDLEY_COMPCERT_VERSION +#endif +#if defined(__COMPCERT_VERSION__) + #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) +#endif + +#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) + #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_COMPCERT_VERSION) + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION) + #undef JSON_HEDLEY_PELLES_VERSION +#endif +#if defined(__POCC__) + #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) +#endif + +#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) + #undef JSON_HEDLEY_PELLES_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_PELLES_VERSION) + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #undef JSON_HEDLEY_MCST_LCC_VERSION +#endif +#if defined(__LCC__) && defined(__LCC_MINOR__) + #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) +#endif + +#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) + #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION) + #undef JSON_HEDLEY_GCC_VERSION +#endif +#if \ + defined(JSON_HEDLEY_GNUC_VERSION) && \ + !defined(__clang__) && \ + !defined(JSON_HEDLEY_INTEL_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_ARM_VERSION) && \ + !defined(JSON_HEDLEY_CRAY_VERSION) && \ + !defined(JSON_HEDLEY_TI_VERSION) && \ + !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ + !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ + !defined(__COMPCERT__) && \ + !defined(JSON_HEDLEY_MCST_LCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION +#endif + +#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_VERSION_CHECK +#endif +#if defined(JSON_HEDLEY_GCC_VERSION) + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) +#else + #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_ATTRIBUTE +#endif +#if \ + defined(__has_attribute) && \ + ( \ + (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ + ) +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) +#else +# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE +#endif +#if defined(__has_attribute) + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE +#endif +#if \ + defined(__has_cpp_attribute) && \ + defined(__cplusplus) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) + #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS +#endif +#if !defined(__cplusplus) || !defined(__has_cpp_attribute) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#elif \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION) && \ + (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ + (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) +#else + #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE +#endif +#if defined(__has_cpp_attribute) && defined(__cplusplus) + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_BUILTIN) + #undef JSON_HEDLEY_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) +#else + #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) + #undef JSON_HEDLEY_GNUC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) + #undef JSON_HEDLEY_GCC_HAS_BUILTIN +#endif +#if defined(__has_builtin) + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) +#else + #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_FEATURE) + #undef JSON_HEDLEY_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) +#else + #define JSON_HEDLEY_HAS_FEATURE(feature) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) + #undef JSON_HEDLEY_GNUC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) + #undef JSON_HEDLEY_GCC_HAS_FEATURE +#endif +#if defined(__has_feature) + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) +#else + #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_EXTENSION) + #undef JSON_HEDLEY_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) +#else + #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) + #undef JSON_HEDLEY_GNUC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) + #undef JSON_HEDLEY_GCC_HAS_EXTENSION +#endif +#if defined(__has_extension) + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) +#else + #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE +#endif +#if defined(__has_declspec_attribute) + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) +#else + #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_HAS_WARNING) + #undef JSON_HEDLEY_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) +#else + #define JSON_HEDLEY_HAS_WARNING(warning) (0) +#endif + +#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) + #undef JSON_HEDLEY_GNUC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_GCC_HAS_WARNING) + #undef JSON_HEDLEY_GCC_HAS_WARNING +#endif +#if defined(__has_warning) + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) +#else + #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + defined(__clang__) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ + (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) + #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_PRAGMA(value) __pragma(value) +#else + #define JSON_HEDLEY_PRAGMA(value) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) + #undef JSON_HEDLEY_DIAGNOSTIC_PUSH +#endif +#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) + #undef JSON_HEDLEY_DIAGNOSTIC_POP +#endif +#if defined(__clang__) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) + #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) +#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") + #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_PUSH + #define JSON_HEDLEY_DIAGNOSTIC_POP +#endif + +/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") +# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") +# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# else +# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ + xpr \ + JSON_HEDLEY_DIAGNOSTIC_POP +# endif +# endif +#endif +#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x +#endif + +#if defined(JSON_HEDLEY_CONST_CAST) + #undef JSON_HEDLEY_CONST_CAST +#endif +#if defined(__cplusplus) +# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) +#elif \ + JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_REINTERPRET_CAST) + #undef JSON_HEDLEY_REINTERPRET_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) +#else + #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_STATIC_CAST) + #undef JSON_HEDLEY_STATIC_CAST +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) +#else + #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) +#endif + +#if defined(JSON_HEDLEY_CPP_CAST) + #undef JSON_HEDLEY_CPP_CAST +#endif +#if defined(__cplusplus) +# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ + ((T) (expr)) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) +# define JSON_HEDLEY_CPP_CAST(T, expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("diag_suppress=Pe137") \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) +# endif +#else +# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") +#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") +#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") +#elif \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") +#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL +#endif + +#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) + #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") +#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) +#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") +#else + #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION +#endif + +#if defined(JSON_HEDLEY_DEPRECATED) + #undef JSON_HEDLEY_DEPRECATED +#endif +#if defined(JSON_HEDLEY_DEPRECATED_FOR) + #undef JSON_HEDLEY_DEPRECATED_FOR +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) +#elif \ + (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) +#elif defined(__cplusplus) && (__cplusplus >= 201402L) + #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") +#else + #define JSON_HEDLEY_DEPRECATED(since) + #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) +#endif + +#if defined(JSON_HEDLEY_UNAVAILABLE) + #undef JSON_HEDLEY_UNAVAILABLE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) +#else + #define JSON_HEDLEY_UNAVAILABLE(available_since) +#endif + +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT +#endif +#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) + #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) +#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) + #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) +#elif defined(_Check_return_) /* SAL */ + #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ +#else + #define JSON_HEDLEY_WARN_UNUSED_RESULT + #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) +#endif + +#if defined(JSON_HEDLEY_SENTINEL) + #undef JSON_HEDLEY_SENTINEL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) +#else + #define JSON_HEDLEY_SENTINEL(position) +#endif + +#if defined(JSON_HEDLEY_NO_RETURN) + #undef JSON_HEDLEY_NO_RETURN +#endif +#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NO_RETURN __noreturn +#elif \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define JSON_HEDLEY_NO_RETURN _Noreturn +#elif defined(__cplusplus) && (__cplusplus >= 201103L) + #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) +#else + #define JSON_HEDLEY_NO_RETURN +#endif + +#if defined(JSON_HEDLEY_NO_ESCAPE) + #undef JSON_HEDLEY_NO_ESCAPE +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) + #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) +#else + #define JSON_HEDLEY_NO_ESCAPE +#endif + +#if defined(JSON_HEDLEY_UNREACHABLE) + #undef JSON_HEDLEY_UNREACHABLE +#endif +#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) + #undef JSON_HEDLEY_UNREACHABLE_RETURN +#endif +#if defined(JSON_HEDLEY_ASSUME) + #undef JSON_HEDLEY_ASSUME +#endif +#if \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_ASSUME(expr) __assume(expr) +#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) + #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) +#elif \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #if defined(__cplusplus) + #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) + #else + #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) + #endif +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() +#elif defined(JSON_HEDLEY_ASSUME) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif +#if !defined(JSON_HEDLEY_ASSUME) + #if defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) + #else + #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) + #endif +#endif +#if defined(JSON_HEDLEY_UNREACHABLE) + #if \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) + #else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() + #endif +#else + #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) +#endif +#if !defined(JSON_HEDLEY_UNREACHABLE) + #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) +#endif + +JSON_HEDLEY_DIAGNOSTIC_PUSH +#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") + #pragma clang diagnostic ignored "-Wpedantic" +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) + #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#endif +#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) + #if defined(__clang__) + #pragma clang diagnostic ignored "-Wvariadic-macros" + #elif defined(JSON_HEDLEY_GCC_VERSION) + #pragma GCC diagnostic ignored "-Wvariadic-macros" + #endif +#endif +#if defined(JSON_HEDLEY_NON_NULL) + #undef JSON_HEDLEY_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else + #define JSON_HEDLEY_NON_NULL(...) +#endif +JSON_HEDLEY_DIAGNOSTIC_POP + +#if defined(JSON_HEDLEY_PRINTF_FORMAT) + #undef JSON_HEDLEY_PRINTF_FORMAT +#endif +#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) +#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) +#elif \ + JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) +#else + #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) +#endif + +#if defined(JSON_HEDLEY_CONSTEXPR) + #undef JSON_HEDLEY_CONSTEXPR +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) + #endif +#endif +#if !defined(JSON_HEDLEY_CONSTEXPR) + #define JSON_HEDLEY_CONSTEXPR +#endif + +#if defined(JSON_HEDLEY_PREDICT) + #undef JSON_HEDLEY_PREDICT +#endif +#if defined(JSON_HEDLEY_LIKELY) + #undef JSON_HEDLEY_LIKELY +#endif +#if defined(JSON_HEDLEY_UNLIKELY) + #undef JSON_HEDLEY_UNLIKELY +#endif +#if defined(JSON_HEDLEY_UNPREDICTABLE) + #undef JSON_HEDLEY_UNPREDICTABLE +#endif +#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) + #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) +#endif +#if \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) +#elif \ + (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ + (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ + })) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ + (__extension__ ({ \ + double hedley_probability_ = (probability); \ + ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ + })) +# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) +# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) +#else +# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) +# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) +# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) +# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) +#endif +#if !defined(JSON_HEDLEY_UNPREDICTABLE) + #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) +#endif + +#if defined(JSON_HEDLEY_MALLOC) + #undef JSON_HEDLEY_MALLOC +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_MALLOC __declspec(restrict) +#else + #define JSON_HEDLEY_MALLOC +#endif + +#if defined(JSON_HEDLEY_PURE) + #undef JSON_HEDLEY_PURE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PURE __attribute__((__pure__)) +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) +# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ + ) +# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") +#else +# define JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_CONST) + #undef JSON_HEDLEY_CONST +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_CONST __attribute__((__const__)) +#elif \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) + #define JSON_HEDLEY_CONST _Pragma("no_side_effect") +#else + #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE +#endif + +#if defined(JSON_HEDLEY_RESTRICT) + #undef JSON_HEDLEY_RESTRICT +#endif +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT restrict +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ + defined(__clang__) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RESTRICT __restrict +#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) + #define JSON_HEDLEY_RESTRICT _Restrict +#else + #define JSON_HEDLEY_RESTRICT +#endif + +#if defined(JSON_HEDLEY_INLINE) + #undef JSON_HEDLEY_INLINE +#endif +#if \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + (defined(__cplusplus) && (__cplusplus >= 199711L)) + #define JSON_HEDLEY_INLINE inline +#elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) + #define JSON_HEDLEY_INLINE __inline__ +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_INLINE __inline +#else + #define JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_ALWAYS_INLINE) + #undef JSON_HEDLEY_ALWAYS_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) +# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_ALWAYS_INLINE __forceinline +#elif defined(__cplusplus) && \ + ( \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ + ) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") +#else +# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE +#endif + +#if defined(JSON_HEDLEY_NEVER_INLINE) + #undef JSON_HEDLEY_NEVER_INLINE +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ + JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ + (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ + (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ + (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ + JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ + JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ + JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") +#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) + #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") +#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) + #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) + #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) +#else + #define JSON_HEDLEY_NEVER_INLINE +#endif + +#if defined(JSON_HEDLEY_PRIVATE) + #undef JSON_HEDLEY_PRIVATE +#endif +#if defined(JSON_HEDLEY_PUBLIC) + #undef JSON_HEDLEY_PUBLIC +#endif +#if defined(JSON_HEDLEY_IMPORT) + #undef JSON_HEDLEY_IMPORT +#endif +#if defined(_WIN32) || defined(__CYGWIN__) +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC __declspec(dllexport) +# define JSON_HEDLEY_IMPORT __declspec(dllimport) +#else +# if \ + JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + ( \ + defined(__TI_EABI__) && \ + ( \ + (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ + ) \ + ) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) +# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) +# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) +# else +# define JSON_HEDLEY_PRIVATE +# define JSON_HEDLEY_PUBLIC +# endif +# define JSON_HEDLEY_IMPORT extern +#endif + +#if defined(JSON_HEDLEY_NO_THROW) + #undef JSON_HEDLEY_NO_THROW +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) + #define JSON_HEDLEY_NO_THROW __declspec(nothrow) +#else + #define JSON_HEDLEY_NO_THROW +#endif + +#if defined(JSON_HEDLEY_FALL_THROUGH) + #undef JSON_HEDLEY_FALL_THROUGH +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) +#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) + #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) +#elif defined(__fallthrough) /* SAL */ + #define JSON_HEDLEY_FALL_THROUGH __fallthrough +#else + #define JSON_HEDLEY_FALL_THROUGH +#endif + +#if defined(JSON_HEDLEY_RETURNS_NON_NULL) + #undef JSON_HEDLEY_RETURNS_NON_NULL +#endif +#if \ + JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) +#elif defined(_Ret_notnull_) /* SAL */ + #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ +#else + #define JSON_HEDLEY_RETURNS_NON_NULL +#endif + +#if defined(JSON_HEDLEY_ARRAY_PARAM) + #undef JSON_HEDLEY_ARRAY_PARAM +#endif +#if \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + !defined(__STDC_NO_VLA__) && \ + !defined(__cplusplus) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_TINYC_VERSION) + #define JSON_HEDLEY_ARRAY_PARAM(name) (name) +#else + #define JSON_HEDLEY_ARRAY_PARAM(name) +#endif + +#if defined(JSON_HEDLEY_IS_CONSTANT) + #undef JSON_HEDLEY_IS_CONSTANT +#endif +#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) + #undef JSON_HEDLEY_REQUIRE_CONSTEXPR +#endif +/* JSON_HEDLEY_IS_CONSTEXPR_ is for + HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #undef JSON_HEDLEY_IS_CONSTEXPR_ +#endif +#if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ + (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) + #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) +#endif +#if !defined(__cplusplus) +# if \ + JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ + JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ + JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) +#endif +# elif \ + ( \ + defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ + !defined(JSON_HEDLEY_PGI_VERSION) && \ + !defined(JSON_HEDLEY_IAR_VERSION)) || \ + (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ + JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ + JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) +#if defined(__INTPTR_TYPE__) + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) +#else + #include + #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) +#endif +# elif \ + defined(JSON_HEDLEY_GCC_VERSION) || \ + defined(JSON_HEDLEY_INTEL_VERSION) || \ + defined(JSON_HEDLEY_TINYC_VERSION) || \ + defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ + JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ + defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ + defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ + defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ + defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ + defined(__clang__) +# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ + sizeof(void) != \ + sizeof(*( \ + 1 ? \ + ((void*) ((expr) * 0L) ) : \ +((struct { char v[sizeof(void) * 2]; } *) 1) \ + ) \ + ) \ + ) +# endif +#endif +#if defined(JSON_HEDLEY_IS_CONSTEXPR_) + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) +#else + #if !defined(JSON_HEDLEY_IS_CONSTANT) + #define JSON_HEDLEY_IS_CONSTANT(expr) (0) + #endif + #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) +#endif + +#if defined(JSON_HEDLEY_BEGIN_C_DECLS) + #undef JSON_HEDLEY_BEGIN_C_DECLS +#endif +#if defined(JSON_HEDLEY_END_C_DECLS) + #undef JSON_HEDLEY_END_C_DECLS +#endif +#if defined(JSON_HEDLEY_C_DECL) + #undef JSON_HEDLEY_C_DECL +#endif +#if defined(__cplusplus) + #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { + #define JSON_HEDLEY_END_C_DECLS } + #define JSON_HEDLEY_C_DECL extern "C" +#else + #define JSON_HEDLEY_BEGIN_C_DECLS + #define JSON_HEDLEY_END_C_DECLS + #define JSON_HEDLEY_C_DECL +#endif + +#if defined(JSON_HEDLEY_STATIC_ASSERT) + #undef JSON_HEDLEY_STATIC_ASSERT +#endif +#if \ + !defined(__cplusplus) && ( \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ + (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ + JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ + defined(_Static_assert) \ + ) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) +#elif \ + (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ + JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) +#else +# define JSON_HEDLEY_STATIC_ASSERT(expr, message) +#endif + +#if defined(JSON_HEDLEY_NULL) + #undef JSON_HEDLEY_NULL +#endif +#if defined(__cplusplus) + #if __cplusplus >= 201103L + #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) + #elif defined(NULL) + #define JSON_HEDLEY_NULL NULL + #else + #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) + #endif +#elif defined(NULL) + #define JSON_HEDLEY_NULL NULL +#else + #define JSON_HEDLEY_NULL ((void*) 0) +#endif + +#if defined(JSON_HEDLEY_MESSAGE) + #undef JSON_HEDLEY_MESSAGE +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_MESSAGE(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(message msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) +#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) +#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) +# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_WARNING) + #undef JSON_HEDLEY_WARNING +#endif +#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") +# define JSON_HEDLEY_WARNING(msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ + JSON_HEDLEY_PRAGMA(clang warning msg) \ + JSON_HEDLEY_DIAGNOSTIC_POP +#elif \ + JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ + JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ + JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) +#elif \ + JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) +#else +# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) +#endif + +#if defined(JSON_HEDLEY_REQUIRE) + #undef JSON_HEDLEY_REQUIRE +#endif +#if defined(JSON_HEDLEY_REQUIRE_MSG) + #undef JSON_HEDLEY_REQUIRE_MSG +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) +# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") +# define JSON_HEDLEY_REQUIRE(expr) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), #expr, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ + __attribute__((diagnose_if(!(expr), msg, "error"))) \ + JSON_HEDLEY_DIAGNOSTIC_POP +# else +# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) +# endif +#else +# define JSON_HEDLEY_REQUIRE(expr) +# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) +#endif + +#if defined(JSON_HEDLEY_FLAGS) + #undef JSON_HEDLEY_FLAGS +#endif +#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) + #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) +#else + #define JSON_HEDLEY_FLAGS +#endif + +#if defined(JSON_HEDLEY_FLAGS_CAST) + #undef JSON_HEDLEY_FLAGS_CAST +#endif +#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) +# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ + JSON_HEDLEY_DIAGNOSTIC_PUSH \ + _Pragma("warning(disable:188)") \ + ((T) (expr)); \ + JSON_HEDLEY_DIAGNOSTIC_POP \ + })) +#else +# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) +#endif + +#if defined(JSON_HEDLEY_EMPTY_BASES) + #undef JSON_HEDLEY_EMPTY_BASES +#endif +#if \ + (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ + JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) + #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) +#else + #define JSON_HEDLEY_EMPTY_BASES +#endif + +/* Remaining macros are deprecated. */ + +#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) + #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK +#endif +#if defined(__clang__) + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) +#else + #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) +#endif + +#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) + #undef JSON_HEDLEY_CLANG_HAS_BUILTIN +#endif +#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) + +#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) + #undef JSON_HEDLEY_CLANG_HAS_FEATURE +#endif +#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) + +#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) + #undef JSON_HEDLEY_CLANG_HAS_EXTENSION +#endif +#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) + +#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) + #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE +#endif +#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) + +#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) + #undef JSON_HEDLEY_CLANG_HAS_WARNING +#endif +#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) + +#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ + + +// This file contains all internal macro definitions (except those affecting ABI) +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +// #include + + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// C++ language standard detection +// if the user manually specified the used C++ version, this is skipped +#if !defined(JSON_HAS_CPP_26) && !defined(JSON_HAS_CPP_23) && !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) + #if (defined(__cplusplus) && __cplusplus > 202302L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202302L) + #define JSON_HAS_CPP_26 + #define JSON_HAS_CPP_23 + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus > 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202002L) + #define JSON_HAS_CPP_23 + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus > 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L) + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus > 201402L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus > 201103L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 + #endif + // the cpp 11 flag is always specified because it is the minimal required version + #define JSON_HAS_CPP_11 +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) + #ifdef JSON_HAS_CPP_17 + #if defined(__cpp_lib_filesystem) + #define JSON_HAS_FILESYSTEM 1 + #elif defined(__cpp_lib_experimental_filesystem) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif !defined(__has_include) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #endif + + // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ + #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__clang_major__) && __clang_major__ < 7 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support + #if defined(_MSC_VER) && _MSC_VER < 1914 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before iOS 13 + #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before macOS Catalina + #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + #endif +#endif + +#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_FILESYSTEM + #define JSON_HAS_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_THREE_WAY_COMPARISON + #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ + && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #else + #define JSON_HAS_THREE_WAY_COMPARISON 0 + #endif +#endif + +#ifndef JSON_HAS_RANGES + // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has a syntax error + #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 + #define JSON_HAS_RANGES 0 + #elif defined(__cpp_lib_ranges) + #define JSON_HAS_RANGES 1 + #else + #define JSON_HAS_RANGES 0 + #endif +#endif + +#ifndef JSON_HAS_STATIC_RTTI + #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0 + #define JSON_HAS_STATIC_RTTI 1 + #else + #define JSON_HAS_STATIC_RTTI 0 + #endif +#endif + +#ifdef JSON_HAS_CPP_17 + #define JSON_INLINE_VARIABLE inline +#else + #define JSON_INLINE_VARIABLE +#endif + +#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) + #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define JSON_NO_UNIQUE_ADDRESS +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#endif + +// allow disabling exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #include + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// allow overriding assert +#if !defined(JSON_ASSERT) + #include // assert + #define JSON_ASSERT(x) assert(x) +#endif + +// allow accessing some private functions (needed by the test suite) +#if defined(JSON_TESTS_PRIVATE) + #define JSON_PRIVATE_UNLESS_TESTED public +#else + #define JSON_PRIVATE_UNLESS_TESTED private +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [&j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer, \ + class BinaryType, \ + class CustomBaseClass> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// Macros to simplify conversion from/to types + +#define NLOHMANN_JSON_EXPAND( x ) x +#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME +#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_PASTE64, \ + NLOHMANN_JSON_PASTE63, \ + NLOHMANN_JSON_PASTE62, \ + NLOHMANN_JSON_PASTE61, \ + NLOHMANN_JSON_PASTE60, \ + NLOHMANN_JSON_PASTE59, \ + NLOHMANN_JSON_PASTE58, \ + NLOHMANN_JSON_PASTE57, \ + NLOHMANN_JSON_PASTE56, \ + NLOHMANN_JSON_PASTE55, \ + NLOHMANN_JSON_PASTE54, \ + NLOHMANN_JSON_PASTE53, \ + NLOHMANN_JSON_PASTE52, \ + NLOHMANN_JSON_PASTE51, \ + NLOHMANN_JSON_PASTE50, \ + NLOHMANN_JSON_PASTE49, \ + NLOHMANN_JSON_PASTE48, \ + NLOHMANN_JSON_PASTE47, \ + NLOHMANN_JSON_PASTE46, \ + NLOHMANN_JSON_PASTE45, \ + NLOHMANN_JSON_PASTE44, \ + NLOHMANN_JSON_PASTE43, \ + NLOHMANN_JSON_PASTE42, \ + NLOHMANN_JSON_PASTE41, \ + NLOHMANN_JSON_PASTE40, \ + NLOHMANN_JSON_PASTE39, \ + NLOHMANN_JSON_PASTE38, \ + NLOHMANN_JSON_PASTE37, \ + NLOHMANN_JSON_PASTE36, \ + NLOHMANN_JSON_PASTE35, \ + NLOHMANN_JSON_PASTE34, \ + NLOHMANN_JSON_PASTE33, \ + NLOHMANN_JSON_PASTE32, \ + NLOHMANN_JSON_PASTE31, \ + NLOHMANN_JSON_PASTE30, \ + NLOHMANN_JSON_PASTE29, \ + NLOHMANN_JSON_PASTE28, \ + NLOHMANN_JSON_PASTE27, \ + NLOHMANN_JSON_PASTE26, \ + NLOHMANN_JSON_PASTE25, \ + NLOHMANN_JSON_PASTE24, \ + NLOHMANN_JSON_PASTE23, \ + NLOHMANN_JSON_PASTE22, \ + NLOHMANN_JSON_PASTE21, \ + NLOHMANN_JSON_PASTE20, \ + NLOHMANN_JSON_PASTE19, \ + NLOHMANN_JSON_PASTE18, \ + NLOHMANN_JSON_PASTE17, \ + NLOHMANN_JSON_PASTE16, \ + NLOHMANN_JSON_PASTE15, \ + NLOHMANN_JSON_PASTE14, \ + NLOHMANN_JSON_PASTE13, \ + NLOHMANN_JSON_PASTE12, \ + NLOHMANN_JSON_PASTE11, \ + NLOHMANN_JSON_PASTE10, \ + NLOHMANN_JSON_PASTE9, \ + NLOHMANN_JSON_PASTE8, \ + NLOHMANN_JSON_PASTE7, \ + NLOHMANN_JSON_PASTE6, \ + NLOHMANN_JSON_PASTE5, \ + NLOHMANN_JSON_PASTE4, \ + NLOHMANN_JSON_PASTE3, \ + NLOHMANN_JSON_PASTE2, \ + NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) +#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) +#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) +#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) +#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) +#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) +#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) +#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) +#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) +#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) +#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) +#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) +#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) +#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) +#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) +#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) +#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) +#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) +#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) +#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) +#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) +#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) +#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) +#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) +#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) +#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) +#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) +#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) +#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) +#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) +#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) +#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) +#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) +#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) +#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) +#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) +#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) +#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) +#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) +#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) +#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) +#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) +#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) +#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) +#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) +#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) +#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) +#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) +#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) +#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) +#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) +#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) +#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) +#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) +#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) +#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) +#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) +#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) +#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) +#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) +#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) +#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) +#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) + +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); +#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1) : nlohmann_json_default_obj.v1; + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE +@since version 3.9.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT +@since version 3.11.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE +@since version 3.11.3 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE +@since version 3.9.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT +@since version 3.11.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE +@since version 3.11.3 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ + template::value, int> = 0> \ + friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + template::value, int> = 0> \ + void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE +@since version 3.12.0 +@sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ +*/ +#define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ + template::value, int> = 0> \ + void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +// inspired from https://stackoverflow.com/a/26745591 +// allows calling any std function as if (e.g., with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + +#ifndef JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_USE_IMPLICIT_CONVERSIONS 1 +#endif + +#if JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_EXPLICIT +#else + #define JSON_EXPLICIT explicit +#endif + +#ifndef JSON_DISABLE_ENUM_SERIALIZATION + #define JSON_DISABLE_ENUM_SERIALIZATION 0 +#endif + +#ifndef JSON_USE_GLOBAL_UDLS + #define JSON_USE_GLOBAL_UDLS 1 +#endif + +#if JSON_HAS_THREE_WAY_COMPARISON + #include // partial_ordering +#endif + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/////////////////////////// +// JSON type enumeration // +/////////////////////////// + +/*! +@brief the JSON type enumeration + +This enumeration collects the different JSON types. It is internally used to +distinguish the stored values, and the functions @ref basic_json::is_null(), +@ref basic_json::is_object(), @ref basic_json::is_array(), +@ref basic_json::is_string(), @ref basic_json::is_boolean(), +@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), +@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), +@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and +@ref basic_json::is_structured() rely on it. + +@note There are three enumeration entries (number_integer, number_unsigned, and +number_float), because the library distinguishes these three types for numbers: +@ref basic_json::number_unsigned_t is used for unsigned integers, +@ref basic_json::number_integer_t is used for signed integers, and +@ref basic_json::number_float_t is used for floating-point numbers or to +approximate integers which do not fit in the limits of their respective type. + +@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON +value with the default value for a given type + +@since version 1.0.0 +*/ +enum class value_t : std::uint8_t +{ + null, ///< null value + object, ///< object (unordered set of name/value pairs) + array, ///< array (ordered collection of values) + string, ///< string value + boolean, ///< boolean value + number_integer, ///< number value (signed integer) + number_unsigned, ///< number value (unsigned integer) + number_float, ///< number value (floating-point) + binary, ///< binary array (ordered collection of bytes) + discarded ///< discarded by the parser callback function +}; + +/*! +@brief comparison operator for JSON types + +Returns an ordering that is similar to Python: +- order: null < boolean < number < object < array < string < binary +- furthermore, each type is not smaller than itself +- discarded values are not comparable +- binary is represented as a b"" string in python and directly comparable to a + string; however, making a binary array directly comparable with a string would + be surprising behavior in a JSON file. + +@since version 1.0.0 +*/ +#if JSON_HAS_THREE_WAY_COMPARISON + inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* +#else + inline bool operator<(const value_t lhs, const value_t rhs) noexcept +#endif +{ + static constexpr std::array order = {{ + 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, + 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, + 6 /* binary */ + } + }; + + const auto l_index = static_cast(lhs); + const auto r_index = static_cast(rhs); +#if JSON_HAS_THREE_WAY_COMPARISON + if (l_index < order.size() && r_index < order.size()) + { + return order[l_index] <=> order[r_index]; // *NOPAD* + } + return std::partial_ordering::unordered; +#else + return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; +#endif +} + +// GCC selects the built-in operator< over an operator rewritten from +// a user-defined spaceship operator +// Clang, MSVC, and ICC select the rewritten candidate +// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) +#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) +inline bool operator<(const value_t lhs, const value_t rhs) noexcept +{ + return std::is_lt(lhs <=> rhs); // *NOPAD* +} +#endif + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief replace all occurrences of a substring by another string + +@param[in,out] s the string to manipulate; changed so that all + occurrences of @a f are replaced with @a t +@param[in] f the substring to replace with @a t +@param[in] t the string to replace @a f + +@pre The search string @a f must not be empty. **This precondition is +enforced with an assertion.** + +@since version 2.0.0 +*/ +template +inline void replace_substring(StringType& s, const StringType& f, + const StringType& t) +{ + JSON_ASSERT(!f.empty()); + for (auto pos = s.find(f); // find the first occurrence of f + pos != StringType::npos; // make sure f was found + s.replace(pos, f.size(), t), // replace with t, and + pos = s.find(f, pos + t.size())) // find the next occurrence of f + {} +} + +/*! + * @brief string escaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to escape + * @return escaped string + * + * Note the order of escaping "~" to "~0" and "/" to "~1" is important. + */ +template +inline StringType escape(StringType s) +{ + replace_substring(s, StringType{"~"}, StringType{"~0"}); + replace_substring(s, StringType{"/"}, StringType{"~1"}); + return s; +} + +/*! + * @brief string unescaping as described in RFC 6901 (Sect. 4) + * @param[in] s string to unescape + * @return unescaped string + * + * Note the order of escaping "~1" to "/" and "~0" to "~" is important. + */ +template +inline void unescape(StringType& s) +{ + replace_substring(s, StringType{"~1"}, StringType{"/"}); + replace_substring(s, StringType{"~0"}, StringType{"~"}); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // size_t + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// struct to capture the start position of the current token +struct position_t +{ + /// the total number of characters read + std::size_t chars_read_total = 0; + /// the number of characters read in the current line + std::size_t chars_read_current_line = 0; + /// the number of lines read + std::size_t lines_read = 0; + + /// conversion to size_t to preserve SAX interface + constexpr operator size_t() const + { + return chars_read_total; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-FileCopyrightText: 2018 The Abseil Authors +// SPDX-License-Identifier: MIT + + + +#include // array +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type +#include // index_sequence, make_index_sequence, index_sequence_for + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using uncvref_t = typename std::remove_cv::type>::type; + +#ifdef JSON_HAS_CPP_14 + +// the following utilities are natively available in C++14 +using std::enable_if_t; +using std::index_sequence; +using std::make_index_sequence; +using std::index_sequence_for; + +#else + +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h +// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. + +//// START OF CODE FROM GOOGLE ABSEIL + +// integer_sequence +// +// Class template representing a compile-time integer sequence. An instantiation +// of `integer_sequence` has a sequence of integers encoded in its +// type through its template arguments (which is a common need when +// working with C++11 variadic templates). `absl::integer_sequence` is designed +// to be a drop-in replacement for C++14's `std::integer_sequence`. +// +// Example: +// +// template< class T, T... Ints > +// void user_function(integer_sequence); +// +// int main() +// { +// // user_function's `T` will be deduced to `int` and `Ints...` +// // will be deduced to `0, 1, 2, 3, 4`. +// user_function(make_integer_sequence()); +// } +template +struct integer_sequence +{ + using value_type = T; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +// index_sequence +// +// A helper template for an `integer_sequence` of `size_t`, +// `absl::index_sequence` is designed to be a drop-in replacement for C++14's +// `std::index_sequence`. +template +using index_sequence = integer_sequence; + +namespace utility_internal +{ + +template +struct Extend; + +// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. +template +struct Extend, SeqSize, 0> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; +}; + +template +struct Extend, SeqSize, 1> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; +}; + +// Recursion helper for 'make_integer_sequence'. +// 'Gen::type' is an alias for 'integer_sequence'. +template +struct Gen +{ + using type = + typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; +}; + +template +struct Gen +{ + using type = integer_sequence; +}; + +} // namespace utility_internal + +// Compile-time sequences of integers + +// make_integer_sequence +// +// This template alias is equivalent to +// `integer_sequence`, and is designed to be a drop-in +// replacement for C++14's `std::make_integer_sequence`. +template +using make_integer_sequence = typename utility_internal::Gen::type; + +// make_index_sequence +// +// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, +// and is designed to be a drop-in replacement for C++14's +// `std::make_index_sequence`. +template +using make_index_sequence = make_integer_sequence; + +// index_sequence_for +// +// Converts a typename pack into an index sequence of the same length, and +// is designed to be a drop-in replacement for C++14's +// `std::index_sequence_for()` +template +using index_sequence_for = make_index_sequence; + +//// END OF CODE FROM GOOGLE ABSEIL + +#endif + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static JSON_INLINE_VARIABLE constexpr T value{}; +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr T static_const::value; +#endif + +template +constexpr std::array make_array(Args&& ... args) +{ + return std::array {{static_cast(std::forward(args))...}}; +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // numeric_limits +#include // char_traits +#include // tuple +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval +#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L + #include // byte +#endif +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +#include // random_access_iterator_tag + +// #include + +// #include + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); + +NLOHMANN_JSON_NAMESPACE_END + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + + + +// #include + + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); + +NLOHMANN_JSON_NAMESPACE_END + +// #include + +// #include + +// #include +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.12.0 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann +// SPDX-License-Identifier: MIT + +#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ + #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + #include // int64_t, uint64_t + #include // map + #include // allocator + #include // string + #include // vector + + // #include + + + /*! + @brief namespace for Niels Lohmann + @see https://github.com/nlohmann + @since version 1.0.0 + */ + NLOHMANN_JSON_NAMESPACE_BEGIN + + /*! + @brief default JSONSerializer template argument + + This serializer ignores the template arguments and uses ADL + ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) + for serialization. + */ + template + struct adl_serializer; + + /// a class to store JSON values + /// @sa https://json.nlohmann.me/api/basic_json/ + template class ObjectType = + std::map, + template class ArrayType = std::vector, + class StringType = std::string, class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = + adl_serializer, + class BinaryType = std::vector, // cppcheck-suppress syntaxError + class CustomBaseClass = void> + class basic_json; + + /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document + /// @sa https://json.nlohmann.me/api/json_pointer/ + template + class json_pointer; + + /*! + @brief default specialization + @sa https://json.nlohmann.me/api/json/ + */ + using json = basic_json<>; + + /// @brief a minimal map-like container that preserves insertion order + /// @sa https://json.nlohmann.me/api/ordered_map/ + template + struct ordered_map; + + /// @brief specialization that maintains the insertion order of object keys + /// @sa https://json.nlohmann.me/api/ordered_json/ + using ordered_json = basic_json; + + NLOHMANN_JSON_NAMESPACE_END + +#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ + + +NLOHMANN_JSON_NAMESPACE_BEGIN +/*! +@brief detail namespace with internal helper functions + +This namespace collects functions that should not be exposed, +implementations of some @ref basic_json methods, and meta-programming helpers. + +@since version 2.1.0 +*/ +namespace detail +{ + +///////////// +// helpers // +///////////// + +// Note to maintainers: +// +// Every trait in this file expects a non-CV-qualified type. +// The only exceptions are in the 'aliases for detected' section +// (i.e., those of the form: decltype(T::member_function(std::declval()))) +// +// In this case, T has to be properly CV-qualified to constraint the function arguments +// (e.g., to_json(BasicJsonType&, const T&)) + +template struct is_basic_json : std::false_type {}; + +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct is_basic_json : std::true_type {}; + +// used by exceptions create() member functions +// true_type for the pointer to possibly cv-qualified basic_json or std::nullptr_t +// false_type otherwise +template +struct is_basic_json_context : + std::integral_constant < bool, + is_basic_json::type>::type>::value + || std::is_same::value > +{}; + +////////////////////// +// json_ref helpers // +////////////////////// + +template +class json_ref; + +template +struct is_json_ref : std::false_type {}; + +template +struct is_json_ref> : std::true_type {}; + +////////////////////////// +// aliases for detected // +////////////////////////// + +template +using mapped_type_t = typename T::mapped_type; + +template +using key_type_t = typename T::key_type; + +template +using value_type_t = typename T::value_type; + +template +using difference_type_t = typename T::difference_type; + +template +using pointer_t = typename T::pointer; + +template +using reference_t = typename T::reference; + +template +using iterator_category_t = typename T::iterator_category; + +template +using to_json_function = decltype(T::to_json(std::declval()...)); + +template +using from_json_function = decltype(T::from_json(std::declval()...)); + +template +using get_template_function = decltype(std::declval().template get()); + +// trait checking if JSONSerializer::from_json(json const&, udt&) exists +template +struct has_from_json : std::false_type {}; + +// trait checking if j.get is valid +// use this trait instead of std::is_constructible or std::is_convertible, +// both rely on, or make use of implicit conversions, and thus fail when T +// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) +template +struct is_getable +{ + static constexpr bool value = is_detected::value; +}; + +template +struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if JSONSerializer::from_json(json const&) exists +// this overload is used for non-default-constructible user-defined-types +template +struct has_non_default_from_json : std::false_type {}; + +template +struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if BasicJsonType::json_serializer::to_json exists +// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. +template +struct has_to_json : std::false_type {}; + +template +struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; + +///////////////// +// char_traits // +///////////////// + +// Primary template of char_traits calls std char_traits +template +struct char_traits : std::char_traits +{}; + +// Explicitly define char traits for unsigned char since it is not standard +template<> +struct char_traits : std::char_traits +{ + using char_type = unsigned char; + using int_type = uint64_t; + + // Redefine to_int_type function + static int_type to_int_type(char_type c) noexcept + { + return static_cast(c); + } + + static char_type to_char_type(int_type i) noexcept + { + return static_cast(i); + } + + static constexpr int_type eof() noexcept + { + return static_cast(std::char_traits::eof()); + } +}; + +// Explicitly define char traits for signed char since it is not standard +template<> +struct char_traits : std::char_traits +{ + using char_type = signed char; + using int_type = uint64_t; + + // Redefine to_int_type function + static int_type to_int_type(char_type c) noexcept + { + return static_cast(c); + } + + static char_type to_char_type(int_type i) noexcept + { + return static_cast(i); + } + + static constexpr int_type eof() noexcept + { + return static_cast(std::char_traits::eof()); + } +}; + +#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L +template<> +struct char_traits : std::char_traits +{ + using char_type = std::byte; + using int_type = uint64_t; + + static int_type to_int_type(char_type c) noexcept + { + return static_cast(std::to_integer(c)); + } + + static char_type to_char_type(int_type i) noexcept + { + return std::byte(static_cast(i)); + } + + static constexpr int_type eof() noexcept + { + return static_cast(std::char_traits::eof()); + } +}; +#endif + +/////////////////// +// is_ functions // +/////////////////// + +// https://en.cppreference.com/w/cpp/types/conjunction +template struct conjunction : std::true_type { }; +template struct conjunction : B { }; +template +struct conjunction +: std::conditional(B::value), conjunction, B>::type {}; + +// https://en.cppreference.com/w/cpp/types/negation +template struct negation : std::integral_constant < bool, !B::value > { }; + +// Reimplementation of is_constructible and is_default_constructible, due to them being broken for +// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). +// This causes compile errors in e.g., Clang 3.5 or GCC 4.9. +template +struct is_default_constructible : std::is_default_constructible {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_constructible : std::is_constructible {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_iterator_traits : std::false_type {}; + +template +struct is_iterator_traits> +{ + private: + using traits = iterator_traits; + + public: + static constexpr auto value = + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value; +}; + +template +struct is_range +{ + private: + using t_ref = typename std::add_lvalue_reference::type; + + using iterator = detected_t; + using sentinel = detected_t; + + // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator + // and https://en.cppreference.com/w/cpp/iterator/sentinel_for + // but reimplementing these would be too much work, as a lot of other concepts are used underneath + static constexpr auto is_iterator_begin = + is_iterator_traits>::value; + + public: + static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; +}; + +template +using iterator_t = enable_if_t::value, result_of_begin())>>; + +template +using range_value_t = value_type_t>>; + +// The following implementation of is_complete_type is taken from +// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ +// and is written by Xiang Fan who agreed to use it in this library. + +template +struct is_complete_type : std::false_type {}; + +template +struct is_complete_type : std::true_type {}; + +template +struct is_compatible_object_type_impl : std::false_type {}; + +template +struct is_compatible_object_type_impl < + BasicJsonType, CompatibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + // macOS's is_constructible does not play well with nonesuch... + static constexpr bool value = + is_constructible::value && + is_constructible::value; +}; + +template +struct is_compatible_object_type + : is_compatible_object_type_impl {}; + +template +struct is_constructible_object_type_impl : std::false_type {}; + +template +struct is_constructible_object_type_impl < + BasicJsonType, ConstructibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + static constexpr bool value = + (is_default_constructible::value && + (std::is_move_assignable::value || + std::is_copy_assignable::value) && + (is_constructible::value && + std::is_same < + typename object_t::mapped_type, + typename ConstructibleObjectType::mapped_type >::value)) || + (has_from_json::value || + has_non_default_from_json < + BasicJsonType, + typename ConstructibleObjectType::mapped_type >::value); +}; + +template +struct is_constructible_object_type + : is_constructible_object_type_impl {}; + +template +struct is_compatible_string_type +{ + static constexpr auto value = + is_constructible::value; +}; + +template +struct is_constructible_string_type +{ + // launder type through decltype() to fix compilation failure on ICPC +#ifdef __INTEL_COMPILER + using laundered_type = decltype(std::declval()); +#else + using laundered_type = ConstructibleStringType; +#endif + + static constexpr auto value = + conjunction < + is_constructible, + is_detected_exact>::value; +}; + +template +struct is_compatible_array_type_impl : std::false_type {}; + +template +struct is_compatible_array_type_impl < + BasicJsonType, CompatibleArrayType, + enable_if_t < + is_detected::value&& + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> +{ + static constexpr bool value = + is_constructible>::value; +}; + +template +struct is_compatible_array_type + : is_compatible_array_type_impl {}; + +template +struct is_constructible_array_type_impl : std::false_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t::value >> + : std::true_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t < !std::is_same::value&& + !is_compatible_string_type::value&& + is_default_constructible::value&& +(std::is_move_assignable::value || + std::is_copy_assignable::value)&& +is_detected::value&& +is_iterator_traits>>::value&& +is_detected::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& +is_complete_type < +detected_t>::value >> +{ + using value_type = range_value_t; + + static constexpr bool value = + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; +}; + +template +struct is_constructible_array_type + : is_constructible_array_type_impl {}; + +template +struct is_compatible_integer_type_impl : std::false_type {}; + +template +struct is_compatible_integer_type_impl < + RealIntegerType, CompatibleNumberIntegerType, + enable_if_t < std::is_integral::value&& + std::is_integral::value&& + !std::is_same::value >> +{ + // is there an assert somewhere on overflows? + using RealLimits = std::numeric_limits; + using CompatibleLimits = std::numeric_limits; + + static constexpr auto value = + is_constructible::value && + CompatibleLimits::is_integer && + RealLimits::is_signed == CompatibleLimits::is_signed; +}; + +template +struct is_compatible_integer_type + : is_compatible_integer_type_impl {}; + +template +struct is_compatible_type_impl: std::false_type {}; + +template +struct is_compatible_type_impl < + BasicJsonType, CompatibleType, + enable_if_t::value >> +{ + static constexpr bool value = + has_to_json::value; +}; + +template +struct is_compatible_type + : is_compatible_type_impl {}; + +template +struct is_compatible_reference_type_impl +{ + using JsonType = uncvref_t; + using CVType = typename std::remove_reference::type; + using Type = typename std::remove_cv::type; + constexpr static bool value = std::is_reference::value && + (!std::is_const::type>::value || std::is_const::value) && + (std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value); +}; + +template +struct is_compatible_reference_type + : is_compatible_reference_type_impl {}; + +template +struct is_constructible_tuple : std::false_type {}; + +template +struct is_constructible_tuple> : conjunction...> {}; + +template +struct is_json_iterator_of : std::false_type {}; + +template +struct is_json_iterator_of : std::true_type {}; + +template +struct is_json_iterator_of : std::true_type +{}; + +// checks if a given type T is a template specialization of Primary +template